2012-09-18 68 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++函数实现浅接口。这绝不是什么大事。