2012-09-18 131 views
13

我在寫一個多線程的C++程序,並希望使用多線程C庫。
該庫的預期,我使用原生系統的方法來創建它的一些工作線程,並通過控制其run()函數中使用如下代碼:混合C++ 11 std ::線程和C系統線程(即pthreads)

void system_specific_thread_init(); 
#ifdef _WIN32 
    DWORD WINAPI system_specific_thread_run(LPVOID unused) 
    { 
     library_run(); 
     return 0; 
    } 

    void system_specific_thread_init() 
    { 
     Createthread(NULL, 0, system_specific_thread_run, NULL, 0, NULL); 
    } 
#else 
    void* system_specific_thread_run(void *unused) 
    { 
     library_run(); 
     return NULL; 
    } 

    void system_specific_thread_init() 
    { 
     pthread_t id; 
     pthread_create(&id, NULL, system_specific_thread_run, NULL); 
    } 
#endif 
system_specific_thread_init(); 

後,它會使用相關的原生系統互斥方法到其他本地系統線程在繼續時調用它的功能是自己的工作。

但是,我正在使用C++ 11 <thread>庫來創建和管理我的所有線程。我希望用std::thread(library_run)創建工作線程,並從其他這樣的線程調用庫函數。

這樣做是否安全,還是DS9K會導致惡魔從我的鼻子飛出?

回答

3

C++標準並未指定C++線程如何與任何其他線程庫交互,但總的來說,我希望C++實現使用底層系統線程庫,因此您的使用應該是安全的。

能夠使用一個使用系統線程庫鎖定原語的第三方庫是一個常見的用例,它應該可以工作(否則C++線程支持在很多真實世界的情況下幾乎沒有用處)。正如Pete指出的那樣,任何涉及線程句柄/ ids的東西都可能更棘手(但不應該通過閱讀您的問題)。

6

C++ 11個線程可能會或可能不會有一個名爲native_handle()的成員函數;它是否存在實現定義。如果存在,則返回native_handle_type類型的對象;它的實現定義了這種類型的對象可用於什麼。所以請閱讀你的文檔。

+1

我不明白這個答案是如何與問題相關的 - 如果C庫只需要使用系統互斥體,那麼就不需要獲得本地線程句柄。 – cmeerw

+0

@Pete請你詳細說明你的答案嗎? –

+0

@LexiR - 我的歉意; @cmeerw是正確的 - 我的答案雖然技術上正確,但並不能真正解決您提出的問題。一般來說,互斥體不依賴於線程細節,因此使用本地互斥體可能是可以的。另一方面,如果你使用std :: mutex(和std :: lock_guard一起),你可以獲得異常安全的鎖定和解鎖,與我上面描述的相同的'native_handle'舞蹈可能會進入系統互斥體。 –

2

這取決於庫實際上在做什麼。使用pthreads作爲模子,這應該不成問題。但是,如果庫實際上試圖使用pthread_join等函數來管理線程,它可能會導致問題。它可能仍然適用於pthread是標準的系統(unix等),因爲std::thread可以作爲一個非常薄的包裝器實現,但是這顯然是非常依賴實現的,並且我不會指望即使對於將來的版本也能工作相同的編譯器。可以使用CreateThread類似的參數。

1

新的C和C++標準(C11和C++ 11)都實現了相同的線程模型,並且它們的接口應該兼容。因此,無論平臺如何爲您提供C++ 11線程的實現,也應該能夠在C中爲您提供相同的內容。如果不是,它肯定只是暫時的。

如果您的平臺具有pthread作爲本地線程模型(可能是POSIX平臺),那麼C++ 11線程幾乎肯定會建立在它之上。但要小心,這兩個線程模型之間的調用約定只是相似的,並不相等。例如,對於pthread,線程函數的返回值是void*,對於C++ 11/C11,線程函數的返回值是int。但是,如果您急於,並且不能等待您的編譯器供應商也提供了C11接口,那麼您可以通過自己的C++函數實現淺接口。這絕不是什麼大事。