หัวข้อ mingw-w64: posix vs win32


129

ฉันกำลังติดตั้ง mingw-w64 บน Windows และมีสองตัวเลือก: เธรด win32 และเธรด posix ฉันรู้ว่าอะไรคือความแตกต่างระหว่างเธรด win32 และ pthreads แต่ฉันไม่เข้าใจว่าความแตกต่างระหว่างสองตัวเลือกนี้คืออะไร ฉันสงสัยว่าถ้าฉันจะเลือกเธรด posix มันจะป้องกันไม่ให้ฉันเรียกใช้ฟังก์ชัน WinAPI เช่น CreateThread

ดูเหมือนว่าตัวเลือกนี้จะระบุว่าโปรแกรมหรือไลบรารีของเธรดใดจะถูกใช้ แต่โดยอะไร โดย GCC, libstdc ++ หรืออย่างอื่น?

ฉันพบสิ่งนี้: ความแตกต่างระหว่าง thread_posixs และ thread_win32 ในพอร์ต gcc ของ windows คืออะไร?

กล่าวโดยย่อสำหรับ mingw เวอร์ชันนี้ threads-posix release จะใช้ posix API และอนุญาตให้ใช้ std :: thread และ threads-win32 จะใช้ win32 API และปิดการใช้งาน std :: thread ในส่วนของ มาตรฐาน.

โอเคถ้าฉันจะเลือก win32 threads std :: thread จะไม่สามารถใช้งานได้ แต่จะยังคงใช้เธรด win32 อยู่ แต่ใช้โดยอะไร?


ใช้โปรแกรมสร้างขึ้นโดยใช้นี้ GCC
devnull

@devnull นี่ไม่ได้กำหนดโดย API ที่ฉันจะใช้ใช่ไหม ถ้าฉันจะเลือก MinGW เวอร์ชัน pthreads แล้วอะไรจะป้องกันไม่ให้ฉันใช้ WinAPI สำหรับเธรด
Simon

gcc จะป้องกันคุณหรือมากกว่า: ไม่เสถียร
jiggunjer

คำตอบ:


124

GCC มาพร้อมกับไลบรารีรันไทม์ของคอมไพเลอร์ (libgcc) ซึ่งใช้สำหรับ (เหนือสิ่งอื่นใด) ซึ่งให้นามธรรม OS ระดับต่ำสำหรับฟังก์ชันที่เกี่ยวข้องกับมัลติเธรดในภาษาที่รองรับ ตัวอย่างที่เกี่ยวข้องมากที่สุดคือ libstdc ++ 's C ++ 11 <thread>, <mutex>และ<future>ซึ่งไม่ได้มีการดำเนินการเสร็จสมบูรณ์เมื่อ GCC ถูกสร้างขึ้นด้วยภายใน Win32 รุ่นเกลียวของมัน MinGW-w64 ให้ winpthreads (การใช้งาน pthreads ที่ด้านบนของ Win32 multithreading API) ซึ่ง GCC สามารถเชื่อมโยงเพื่อเปิดใช้งานคุณสมบัติแฟนซีทั้งหมดได้

ฉันต้องเน้นว่าตัวเลือกนี้ไม่ได้ห้ามให้คุณเขียนโค้ดใด ๆ ที่คุณต้องการ ( ไม่มีผลอย่างแน่นอนต่อ API ที่คุณสามารถเรียกใช้รหัสของคุณได้) มันสะท้อนเฉพาะสิ่งที่ไลบรารีรันไทม์ของ GCC (libgcc / libstdc ++ / ... ) ใช้สำหรับการทำงานเท่านั้น ข้อแม้ที่กล่าวโดย @James ไม่มีส่วนเกี่ยวข้องกับโมเดลเธรดภายในของ GCC แต่เป็นการใช้งาน CRT ของ Microsoft

สรุป:

  • posix: เปิดใช้งานคุณสมบัติมัลติเธรด C ++ 11 / C11 ทำให้ libgcc ขึ้นอยู่กับ libwinpthreads ดังนั้นแม้ว่าคุณจะไม่ได้เรียกใช้ pthreads API โดยตรง แต่คุณจะแจกจ่าย winpthreads DLL ไม่มีอะไรผิดปกติกับการแจกจ่าย DLL อีกหนึ่งรายการกับแอปพลิเคชันของคุณ
  • win32: ไม่มีฟีเจอร์มัลติเธรด C ++ 11

ไม่มีผลต่อรหัสผู้ใช้ใด ๆ ที่เรียก Win32 APIs หรือ pthreads API คุณสามารถใช้ได้ทั้งสองอย่างเสมอ


7
คุณสามารถเชื่อมโยงรันไทม์ gcc และ winpthreads แบบคงที่ได้ตลอดเวลาโดยไม่จำเป็นต้องรวม DLL
Alexander Shishenko

3
ฉันใช้เวลาสักพักในการค้นหาตัวเลือกที่เกี่ยวข้องบน Linux ดังนั้นในกรณีที่มันช่วยคนอื่น: แพคเกจg++-mingw-w64-x86-64มีไฟล์สองไฟล์x86_64-w64-mingw32-g++-win32และx86_64-w64-mingw32-g++-posixและx86_64-w64-mingw32-g++ถูกตั้งนามแฝงเป็นหนึ่งในนั้น ดูupdate-alternatives --display x86_64-w64-mingw32-g++.
สตูเบสิ

อืมคุณพูดว่า "... ซึ่งไม่มีการใช้งานที่สมบูรณ์เมื่อ GCC สร้างขึ้นด้วยโมเดลเธรด Win32 ภายใน .... MinGW-w64 ให้ winpthreads (การใช้งาน pthreads ที่ด้านบนของ Win32 multithreading API) ซึ่ง GCC สามารถ จากนั้นเชื่อมโยงเพื่อเปิดใช้งานคุณลักษณะแฟนซีทั้งหมด " ดังนั้นหากฉันเลือกรุ่น win32 GCC ยังคงสามารถเปิดใช้งานคุณสมบัติทั้งหมดได้เนื่องจากใช้ประโยชน์จาก winpthreads? แต่ในหัวข้อย่อยด้านล่างเขียนว่า "win32: No C ++ 11 multithreading features" ฉันไม่เข้าใจ. "GCC ใดที่สามารถเชื่อมโยงไปยัง ... " ได้หมายความว่าถ้าฉันไม่เลือก win32 ก็สามารถเลือก ... ?
Johannes Schaub - litb

@ JohannesSchaub-litb อืมไม่สิ การกำหนดค่าของ GCC จับคู่การเลือกรูปแบบเธรดภายในไปยังคุณสมบัติที่เปิดใช้งานของ libstdc ++ เนื่องจากส่วนหลังถูกสร้างขึ้นบนกระดาษห่อหุ้ม "gthread" ภายในของ GCC (ซึ่งเป็นเพียงส่วนที่เป็นนามธรรมของเธรดแบบ posix แบบบางส่วนพื้นฐานสำหรับคุณลักษณะ C ++ 11 หายไป ในชั้นว่าเมื่อคุณใช้--threads=win32. ดังนั้นตราบใดที่บิตที่หายไปไม่ได้ดำเนินการใน GCC คุณต้องกำหนดค่า GCC ด้วย--threads=win32.
rubenvb

ฉันสามารถใช้ไลบรารีที่คอมไพล์ล่วงหน้าของ mingw ของ qt ซึ่งใช้ -win32 กับไลบรารีอื่นที่ใช้ -posix และใช้ไลบรารีทั้งสองในโปรแกรมเดียวกันได้หรือไม่
Johannes Schaub - litb

16

บางส่วนของรันไทม์ GCC (โดยเฉพาะการจัดการข้อยกเว้น) ขึ้นอยู่กับโมเดลเธรดที่ใช้ ดังนั้นหากคุณใช้เวอร์ชันรันไทม์ที่สร้างด้วยเธรด POSIX แต่ตัดสินใจสร้างเธรดในโค้ดของคุณเองด้วย Win32 APIs คุณอาจมีปัญหาในบางจุด

แม้ว่าคุณจะใช้รันไทม์ Win32 threading เวอร์ชันเธรด แต่ก็ไม่ควรเรียก Win32 API โดยตรง อ้างจากคำถามที่พบบ่อย MinGW :

เนื่องจาก MinGW ใช้ไลบรารีรันไทม์ Microsoft C มาตรฐานที่มาพร้อมกับ Windows คุณควรระมัดระวังและใช้ฟังก์ชันที่ถูกต้องเพื่อสร้างเธรดใหม่ โดยเฉพาะอย่างยิ่งCreateThreadฟังก์ชันนี้จะไม่ตั้งค่าสแต็กอย่างถูกต้องสำหรับไลบรารีรันไทม์ C คุณควรใช้_beginthreadexแทนซึ่ง (เกือบ) เข้ากันได้กับCreateThread.


7
ในกรณีนี้แล้วไลบรารีเธรดของบุคคลที่สามเช่น boost หรือ Qt ล่ะ? มีวิธีใดบ้างที่คุณจะใช้ไลบรารีเหล่านี้กับ mingw64 โดยไม่ต้องค้นหาไลบรารีเธรดพื้นฐานสำหรับสิ่งเหล่านี้ จะเกิดอะไรขึ้นถ้าฉันตัดสินใจใช้ boost :: threads ที่มี posix variant ของ mingw โดยพลการ
tantuni

1
@ user460153 ข้อมูลบางส่วนqt-project.org/wiki/…
Alex V.

10
คำตอบนี้ผิด รันไทม์ของ GCC ไม่มีผลต่อ Win32 API เลย แต่อย่างใด
rubenvb

อ่านรายการคำถามที่พบบ่อยที่เชื่อมโยง คำตอบนี้ถูกต้อง
Daira Hopwood

13

โปรดทราบว่าตอนนี้คุณสามารถใช้ C ++ 11 std :: thread บางตัวในโหมด win32 threading ได้แล้ว อะแดปเตอร์เฉพาะส่วนหัวเหล่านี้ทำงานได้ทันทีสำหรับฉัน: https://github.com/meganz/mingw-std-threads

จากประวัติการแก้ไขดูเหมือนว่ามีความพยายามล่าสุดที่จะทำให้สิ่งนี้เป็นส่วนหนึ่งของรันไทม์ mingw64

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.