我正在读书pthread.h
; 条件变量相关函数(如pthread_cond_wait(3)
)需要互斥量作为参数.为什么?据我所知,我将创建一个互斥体只是用作该参数?那个互斥锁应该做什么?
我在某处读到我们应该在调用pthread_cond_signal之前锁定互斥锁并在调用它后解锁互斥锁:
pthread_cond_signal()例程用于发信号(或唤醒)正在等待条件变量的另一个线程.它应该在锁定互斥锁后调用,并且必须解锁互斥锁才能完成pthread_cond_wait()例程.
我的问题是:在不锁定互斥锁的情况下调用pthread_cond_signal或pthread_cond_broadcast方法是不是可以?
我对使用有点困惑std::condition_variable
.我明白我必须创建unique_lock
一个mutex
调用之前condition_variable.wait()
.我无法找到是我是否也应该调用之前获得一个独特的锁notify_one()
或notify_all()
.
cppreference.com上的示例存在冲突.例如,notify_one页面提供了以下示例:
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cout << "Waiting... \n";
cv.wait(lk, []{return i == 1;});
std::cout << "...finished waiting. i == 1\n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying...\n";
cv.notify_one();
std::unique_lock<std::mutex> lk(cv_m);
i = 1;
while (!done) {
lk.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1)); …
Run Code Online (Sandbox Code Playgroud) 我正在研究的项目使用多个线程来处理文件集合.每个线程都可以将文件添加到要处理的文件列表中,因此我将(我认为是)一个线程安全的队列放在一起.相关部分如下:
// qMutex is a std::mutex intended to guard the queue
// populatedNotifier is a std::condition_variable intended to
// notify waiting threads of a new item in the queue
void FileQueue::enqueue(std::string&& filename)
{
std::lock_guard<std::mutex> lock(qMutex);
q.push(std::move(filename));
// Notify anyone waiting for additional files that more have arrived
populatedNotifier.notify_one();
}
std::string FileQueue::dequeue(const std::chrono::milliseconds& timeout)
{
std::unique_lock<std::mutex> lock(qMutex);
if (q.empty()) {
if (populatedNotifier.wait_for(lock, timeout) == std::cv_status::no_timeout) {
std::string ret = q.front();
q.pop();
return ret;
}
else {
return std::string();
}
}
else …
Run Code Online (Sandbox Code Playgroud) 我确定互斥是不够的,这就是条件变量概念存在的原因; 但它打败了我,当一个条件变量必不可少时,我无法用一个具体的场景来说服自己.
条件变量,互斥锁和锁定问题的接受答案之间的区别是条件变量是a
锁定"信号"机制.当线程需要等待资源变得可用时使用它.线程可以在CV上"等待",然后资源生成器可以"发出信号"变量,在这种情况下,等待CV的线程会得到通知并可以继续执行
我感到困惑的是,一个线程也可以在互斥锁上等待,当它被发出信号时,只是意味着该变量现在可用,为什么我需要一个条件变量?
PS:此外,无论如何,需要一个互斥锁来保护条件变量,当我的视力更加偏向于看不到条件变量的目的时.
multithreading synchronization operating-system mutex condition-variable
我还没有找到模块中类Condition
和Event
类之间差异的明确解释threading
.是否有一个明确的用例,其中一个比另一个更有帮助?我可以找到的所有示例都使用生产者 - 消费者模型作为示例,这queue.Queue
将是更直接的解决方案.
目前,我正在使用std::thread
C++ 11 实现一个多线程项目.我std::condition_variable
用来同步线程.详细地说,一个消费者函数从全局任务队列调用wait()
成员函数std::condition_variable
等待任务,另一个生成器函数生成并将任务放入队列.但我不知道notify_all()
和notify_one()
成员函数之间的区别std::condition_variable
.我应该在生产者函数中使用哪个函数?谢谢!
我试图理解新的C++ 11标准中的基本多线程机制.我能想到的最基本的例子如下:
这个例子也被用在许多关于多线程的学校书籍中,关于通信过程的一切都很好.但是,在停止使用者线程时我遇到了问题.
我希望消费者运行直到它获得明确的停止信号(在大多数情况下,这意味着我等待生产者完成所以我可以在程序结束之前停止消费者).不幸的是,C++ 11线程缺少一种中断机制(例如我从Java中的多线程中知道).因此,我必须使用标志isRunning
来表示我想要一个线程停止.
现在的主要问题是:在我停止生产者线程之后,队列为空并且消费者在等待a condition_variable
再次填充队列时获取信号.所以我需要通过notify_all()
在退出之前调用变量来唤醒线程.
我找到了一个有效的解决方案,但似乎有些混乱.下面列出了示例代码(很抱歉,但不知何故,我无法为"最小"最小示例减少代码大小):
队列类:
class Queue{
public:
Queue() : m_isProgramStopped{ false } { }
void push(int i){
std::unique_lock<std::mutex> lock(m_mtx);
m_q.push(i);
m_cond.notify_one();
}
int pop(){
std::unique_lock<std::mutex> lock(m_mtx);
m_cond.wait(lock, [&](){ return !m_q.empty() || m_isProgramStopped; });
if (m_isProgramStopped){
throw std::exception("Program stopped!");
}
int x = m_q.front();
m_q.pop();
std::cout << "Thread " << std::this_thread::get_id() << " popped " << x << "." << std::endl;
return x;
}
void stop(){
m_isProgramStopped = …
Run Code Online (Sandbox Code Playgroud) 首先是一个小小的上下文:我正在学习C++ 11中的线程,为此目的,我正在尝试构建一个actor
小类,基本上(我将异常处理和传播内容留下),如下所示:
class actor {
private: std::atomic<bool> stop;
private: std::condition_variable interrupt;
private: std::thread actor_thread;
private: message_queue incoming_msgs;
public: actor()
: stop(false),
actor_thread([&]{ run_actor(); })
{}
public: virtual ~actor() {
// if the actor is destroyed, we must ensure the thread dies too
stop = true;
// to this end, we have to interrupt the actor thread which is most probably
// waiting on the incoming_msgs queue:
interrupt.notify_all();
actor_thread.join();
}
private: virtual void run_actor() {
try { …
Run Code Online (Sandbox Code Playgroud)