简体   繁体   English

C ++ 11互斥是否与非C ++ 11创建的线程兼容?

[英]Is a C++11 mutex compatible with threads NOT created with C++11?

I'm learning C++11 and have run into a threading issue. 我正在学习C ++ 11并且遇到了线程问题。 My general question: are C++11 mutexes compatible with threads not created with C++11's standard libraries? 我的一般问题:C ++ 11互斥体是否与非C ++ 11标准库创建的线程兼容?

I would like to safely share information between a thread created with C++11 and another thread created by a third-party library that I have no control over. 我想安全地在用C ++ 11创建的线程和由我无法控制的第三方库创建的另一个线程之间共享信息。

For example, my application uses PortAudio, which creates its own thread for audio output. 例如,我的应用程序使用PortAudio,它为音频输出创建自己的线程。 I'm not sure if it's using pthreads, or OS-specific threading libraries, but I do know that PortAudio is NOT written in C++11. 我不确定它是使用pthreads还是特定于OS的线程库,但我知道PortAudio不是用C ++ 11编写的。 I want to safely share data between a GUI thread (using a C++11 thread) and the PortAudio thread using a mutex. 我想安全地在GUI线程(使用C ++ 11线程)和使用互斥锁的PortAudio线程之间共享数据。

Similarly, can I use a C++11 mutex to synchronize QT QThreads and C++11 threads? 同样,我可以使用C ++ 11互斥锁来同步QT QThreads和C ++ 11线程吗?

Are C++11 mutexes compatible with threads not created with C++11's standard libraries? C ++ 11互斥体是否与非C ++ 11标准库创建的线程兼容?

The C++ standard does not define a "thread" as something exclusively created by the C++ standard library. C ++标准没有将“线程”定义为C ++标准库专门创建的东西。

1.10 Multi-threaded executions and data races [intro.multithread] 1.10多线程执行和数据竞争[intro.multithread]

1 A thread of execution (also known as a thread) is a single flow of control within a program, including the initial invocation of a specific top-level function, and recursively including every function invocation subsequently executed by the thread. 1执行线程(也称为线程)是程序中的单个控制流,包括特定顶级函数的初始调用,并递归地包括随后由线程执行的每个函数调用。

So, I would conclude the answer to your question is "yes". 所以,我会得出结论,你的问题的答案是肯定的。

Obviously, the C++ standard doesn't make any guarantees about compatebility with other systems. 显然,C ++标准不保证与其他系统的兼容性。 Part of the reason the C and C++ standards added threading facilities was to standardize on one threading system. C和C ++标准添加线程设施的部分原因是在一个线程系统上进行标准化。

In practice it is expected that the C and C++ threads library is built to integrate with a platform threading system if there is one. 在实践中,期望C和C ++线程库被构建为与平台线程系统集成(如果有的话)。 For example, on platforms using pthreads the expectation is that pthreads are used where appropriate to buildtge standard library threading facilities (as far as I know there is no pthreads interface for the various atomic operations, ie, the standard library may need to provide its own synchronization primitives). 例如,在使用pthreads的平台上,期望在适当的地方使用pthread来构建标准库线程设施(据我所知,各种原子操作没有pthreads接口,即标准库可能需要提供自己的同步原语)。

The standard library classes provide access to the underlying representation through the native_handle() methods. 标准库类通过native_handle()方法提供对底层表示的访问。 A standard library should implement what is returned from these and, eg, if pthreads types are provided it seems safe to assume that this particular standard library will play nice with pthreads. 标准库应该实现从这些返回的内容,例如,如果提供了pthreads类型,似乎可以安全地假设这个特定的标准库将与pthreads一起使用。

The C++11 standard specifies that mutexes should work with any kind of 'execution agent', including different thread libraries. C ++ 11标准规定互斥锁应该与任何类型的“执行代理”一起使用,包括不同的线程库。 Here are some relevant quotes from the standard which I think answer the question conclusively: 以下是该标准的一些相关引用,我认为最终可以回答这个问题:

Mutex requirements 互斥要求

A mutex object facilitates protection against data races and allows safe synchronization of data between execution agents (30.2.5). 互斥对象有助于防止数据争用,并允许执行代理之间的数据安全同步(30.2.5)。 An execution agent owns a mutex from the time it successfully calls one of the lock functions until it calls unlock. 执行代理在成功调用其中一个锁定函数之前拥有一个互斥锁,直到它调用unlock。

Requirements for Lockable types 可锁定类型的要求

An execution agent is an entity such as a thread that may perform work in parallel with other execution agents. 执行代理是诸如可以与其他执行代理并行执行工作的线程之类的实体。 [Note: Implementations or users may introduce other kinds of agents such as processes or thread-pool tasks. [注意:实现或用户可能会引入其他类型的代理,例如进程或线程池任务。 —end note ] The calling agent is determined by context, eg the calling thread that contains the call, and so on. -end note]调用代理由上下文确定,例如包含调用的调用线程,等等。

It is inconceivable that C++11's threading implementation will be incompatible with the platform's native threading implementation because any practical program using C++11 threads is going to call into platform libraries, and those libraries may themselves be threaded or make thread related calls (to mutexes for example). 不可思议的是,C ++ 11的线程实现将与平台的本机线程实现不兼容,因为任何使用C ++ 11线程的实际程序都将调用平台库,这些库本身可能是线程化的或与线程相关的调用(以互斥为例)。

The C++11 library implementation for threads is not of course obliged to use the high level native threading library (say, pthreads or windows threads) but it probably will, for which purpose as has been mentioned there is a std::thread::native_handle() method to get the native handle. 线程的C ++ 11库实现当然不必使用高级本机线程库(例如,pthreads或windows线程),但它可能会出于某种目的,如上所述,有一个std :: thread: :native_handle()方法获取本机句柄。 However, even where it does not use the high level native implementation, it will have to use the same low level kernel primitives underneath. 但是,即使它不使用高级本机实现,它也必须在下面使用相同的低级内核原语。

In all conceivable circumstances it should therefore be perfectly safe to use C++11 mutexes with thread instances created by native library calls, and vice versa, and mix any other native or C++ library synchronization calls. 因此,在所有可能的情况下,将C ++ 11互斥锁与本机库调用创建的线程实例一起使用应该是完全安全的,反之亦然,并混合任何其他本机或C ++库同步调用。 There may indeed be cases where it is necessary to do so. 确实可能存在必须这样做的情况。 For example, the C++11 library does not at present provide thread pools or read-write locks (shared mutexes). 例如,C ++ 11库目前不提供线程池或读写锁(共享互斥锁)。 You might want to use native read-write locks with threads started using std::thread, or use one of the many thread pool implementations provided by third party libraries in your C++ program. 您可能希望对使用std :: thread启动的线程使用本机读写锁,或者使用C ++程序中第三方库提供的众多线程池实现之一。

The only caveat to observe is that trying to mix C++11 threads (which will in practice be obliged to use kernel threads in one way or another for the reasons mentioned above) with thread libraries which do not use kernel threads at all (for example, libraries based on green threads or "user" threads), is likely to lead you into trouble. 需要注意的唯一需要注意的是,尝试将C ++ 11线程(实际上必须以某种方式使用内核线程,出于上述原因)与不使用内核线程的线程库混合(对于例如,基于绿色线程或“用户”线程的库,可能会让您陷入困境。

Edit: In support of this I notice that §30.3 of C++11 states, albeit non-normatively, that "These threads [std::thread threads] are intended to map one-to-one with operating system threads". 编辑:为了支持这一点,我注意到C ++ 11的§30.3,尽管是非规范性的,但是“这些线程[std :: thread threads]旨在与操作系统线程一对一映射”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM