假设我有一个带有3个POSIX线程的C程序,共享一个全局变量,互斥量和条件变量,其中两个执行以下的伪代码:
...process data...
pthread_mutex_lock( &mutex );
variable = data_ptr;
pthread_cond_signal( &cond );
pthread_mutex_unlock( &mutex );
Run Code Online (Sandbox Code Playgroud)
第三次运行:
while(1) {
while( variable == NULL ) {
pthread_mutex_wait( &cond, &mutex );
}
printf( "Data is %d", *variable );
}
Run Code Online (Sandbox Code Playgroud)
假设第三个线程将看到前两个中的每一个的数据是否安全?
换句话说,如果一个线程在互斥锁和一个条件变量上作用,是否可以安全地假设它是下一个获取锁定的,如果它被发出信号,而不是某个其他线程可能正在等待锁?
在以下博文中:
有一个'推送'方法定义如下:
void push(Data const& data)
{
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么在scoped_lock变量上调用了一个显式的'lock.unlock()'?
它的目的是什么?
是否可以安全删除,导致'notify_one'方法调用在scoped_mutex的范围内?
我试图使用c ++ 11并发制作生产者 - 消费者方法.类的wait方法condition_variable有一个谓词作为第二个参数,所以我想到使用lambda函数:
struct LimitedBuffer {
int* buffer, size, front, back, count;
std::mutex lock;
std::condition_variable not_full;
std::condition_variable not_empty;
LimitedBuffer(int size) : size(size), front(0), back(0), count(0) {
buffer = new int[size];
}
~LimitedBuffer() {
delete[] buffer;
}
void add(int data) {
std::unique_lock<std::mutex> l(lock);
not_full.wait(l, [&count, &size]() {
return count != size;
});
buffer[back] = data;
back = (back+1)%size;
++count;
not_empty.notify_one();
}
int extract() {
std::unique_lock<std::mutex> l(lock);
not_empty.wait(l, [&count]() {
return count != 0;
});
int …Run Code Online (Sandbox Code Playgroud) 在网上搜索并阅读了stackoverflow上的问题答案后,我找不到我的问题的答案。
该等待在线程B中被调用,它解锁互斥锁,从而允许其他人访问条件变量(用于发出信号)。然后,当在线程A中发出条件变量的信号时,线程B唤醒,线程B再次锁定互斥锁。
当线程A通过信号通知条件变量唤醒线程B时,线程B被唤醒,请锁定互斥锁。
我从教程中了解到,每当发出线程B信号时,它就会立即锁定互斥量。但是,示例与此相反,当线程B被信号通知并唤醒后,线程A继续执行,有时线程B锁定互斥锁。
我的问题是线程B(在下面的示例中为消费者)何时锁定互斥锁?就在线程B接收信号的那一刻?还是取决于线程调度程序?
我没有找到任何解释。
我正在考虑以下示例的情况:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int buffer[100];
int loops = 5;
int length = 0;
void *producer(void *arg) {
int i,j;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
buffer[length++] = i;
printf("producer length %d\n", length);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
pthread_mutex_lock(&mutex);
while(length == 0) {
printf(" consumer waiting...\n");
pthread_cond_wait(&cond, &mutex);
}
int item …Run Code Online (Sandbox Code Playgroud) 线程调用后pthread_cond_timedwait,它返回ETIMEDOUT,线程是否拥有互斥锁?
我最初会认为不,但似乎我们必须pthread_mutex_unlock在pthread_cond_timedwait回归后打电话ETIMEDOUT.
该文件说:
成功返回后,互斥锁应被锁定并由调用线程拥有.
因此,在不成功返回(返回值!= 0)时,我认为互斥锁不属于.
但是,如果我们不叫pthread_mutex_unlock后ETIMEDOUT,互斥似乎是一个破碎的状态(即我不能让另一个线程来收购它,它只是档).
该文档也暗示了这一点,因为它们总是解锁互斥锁,无论返回值如何pthread_cond_timedwait:
(void) pthread_mutex_lock(&t.mn);
t.waiters++;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5;
rc = 0;
while (! mypredicate(&t) && rc == 0)
rc = pthread_cond_timedwait(&t.cond, &t.mn, &ts);
t.waiters--;
if (rc == 0) setmystate(&t);
(void) pthread_mutex_unlock(&t.mn);
Run Code Online (Sandbox Code Playgroud)
那么,线程总是在获得互斥量之后pthread_cond_timedwait?它实际上没有意义,因为为了再次获取互斥锁,调用必须阻止超过指定的时间.
你好我有以下代码:
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id (int id) {
std::unique_lock<std::mutex> lock(mtx);
while (!ready) cv.wait(lock);
// ...
std::cout << "thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lock(mtx);
ready = true;
cv.notify_all();
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);
std::cout << …Run Code Online (Sandbox Code Playgroud) 我对conditions_variables如何使用它们(安全地)感到困惑。在我的应用程序中,我有一个创建 gui 线程的类,但是当 gui 由 gui 线程构建时,主线程需要等待。
情况与下面的函数相同。主线程创建互斥锁、锁和condition_variable. 然后它使线程。虽然这worker thread还没有通过某个点(此处打印数字),但不允许主线程继续(即必须wait打印所有数字)。
condition_variables在这种情况下如何正确使用?另外,我读到自发唤醒是一个问题。我该如何处理它们?
int main()
{
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
std::condition_variable convar;
auto worker = std::thread([&]{
/* Do some work. Main-thread can not continue. */
for(int i=0; i<100; ++i) std::cout<<i<<" ";
convar.notify_all(); // let main thread continue
std::cout<<"\nworker done"<<std::endl;
});
// The main thread can do some work but then must wait until the worker has done it's calculations.
/* do some stuff …Run Code Online (Sandbox Code Playgroud) 我正在学习condition_variable并运行一些例子.我很好奇,如果我对块进行注释,为什么以下代码会出现死锁.这是使用condition_variable的简单消费者和生产者示例.我认为这是一个僵局问题,不是吗?
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx;
condition_variable cv;
int cargo = 0;
bool shipment_available()
{
return cargo != 0;
}
void consume(int cnt)
{
for (int i = 0; i < cnt; i++)
{
unique_lock<mutex> lck(mtx);
cv.wait(lck, shipment_available);
printf("%d\n", cargo);
cargo = 0;
}
}
int main()
{
thread consumer_thread(consume, 10);
for (int i = 0; i < 10; i++)
{
//while (shipment_available()) // Dead lock without this block
//{
// std::this_thread::yield(); …Run Code Online (Sandbox Code Playgroud) std::mutex我正在尝试在和的帮助下在 C++ 中创建一个线程安全队列std::condition_variable。代码
#include <iostream>
#include<thread>
#include<queue>
#include<atomic>
#include<mutex>
#include<condition_variable>
using namespace std;
template<class T>
class SafeQueue{
public:
queue<T>qu;
mutex mut;
condition_variable cv;
SafeQueue(){}
SafeQueue(queue<T>q):qu(q){}
void push(int val){
unique_lock<mutex>uq(mut);
cv.wait(uq,[&](){return qu.empty();});
qu.push(val);
uq.unlock();
}
bool isEmpty(){
// unique_lock<mutex>uq(mut);
// uq.unlock();
cv.notify_all();
return qu.empty();
}
};
void inc(SafeQueue<int>& sq){
for(int i=0;i<10;i++)
continue;
if(sq.isEmpty())
sq.push(1);
}
void inc1(SafeQueue<int>& sq){
for(int i=0;i<10;i++)
continue;
if(sq.isEmpty())
sq.push(2);
}
int main(){
queue<int>qu;
SafeQueue<int> sq(qu);
thread t1(inc,ref(sq));
thread t2(inc1,ref(sq));
t1.join();
t2.join();
cout<<sq.qu.front();
}
Run Code Online (Sandbox Code Playgroud)
线程安全队列应该 …
std::condition_variable 是第一次检查条件,还是必须等待别人通知?