- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近正在测试std::condition_variable,测试后发现它与pthread_cond_t有很大的不同,我想知道我的测试是否有错误?还是 std::condition_variable 与 pthread_cond_t 真的完全不同?
pthread_cond_t 源代码如下,在 gcc 4.4.6 编译:
pthread_cond_t condA = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int ProcessRow = 0 ;
#define LOOPCNT 10
void *producer()
{
int idx ;
for(idx=0;idx<LOOPCNT;idx++)
{
//pthread_mutex_lock(&mutex);
__sync_add_and_fetch(&ProcessRow,1) ;
pthread_cond_signal(&condA);
printf("sending signal...(%d)\n",ProcessRow) ;
//pthread_mutex_unlock(&mutex);
}
printf("I am out ... \n") ;
}
void *consumer()
{
int icnt = 0 ;
while(1)
{
pthread_mutex_lock(&mutex);
while (ProcessRow <= 0)
pthread_cond_wait(&condA, &mutex);
pthread_mutex_unlock(&mutex); // I forget to add unlock to fail this test
__sync_sub_and_fetch(&ProcessRow,1) ;
++icnt ;
printf("receving=(%d)\n",ProcessRow) ;
usleep(10000) ;
}
printf("(%d)\n",ProcessRow) ;
}
输出:
sending signal...(1)
sending signal...(2)
sending signal...(3)
sending signal...(4)
sending signal...(5)
sending signal...(6)
sending signal...(7)
sending signal...(8)
sending signal...(9)
sending signal...(10)
I am out ...
receving=(9)
看起来像 pthread_cond_wait 中的 comsumer 线程 block ,因此“接收”仅打印一次 !!!!
然后下面的测试是针对 std::condition_variable !!!!
下面的binsem.hpp来自 https://gist.github.com/yohhoy/2156481
稍作修改,编译为 g++ 4.8.1
class binsem {
public:
explicit binsem(int init_count = count_max)
: count_(init_count) {}
// P-operation / acquire
void wait()
{
std::unique_lock<std::mutex> lk(m_);
cv_.wait(lk, [this]{ return 0 < count_; });
--count_;
}
bool try_wait()
{
std::lock_guard<std::mutex> lk(m_);
if (0 < count_)
{
--count_;
return true;
} else
{
return false;
}
}
// V-operation / release
void signal()
{
std::lock_guard<std::mutex> lk(m_);
//if (count_ < count_max) // I mark here
//{ // I mark here
++count_;
cv_.notify_one();
//} // I mark here
}
// Lockable requirements
void lock() { wait(); }
bool try_lock() { return try_wait(); }
void unlock() { signal(); }
private:
static const int count_max = 1;
int count_;
std::mutex m_;
std::condition_variable cv_;
};
和我的来源:
#define LOOPCNT 10
atomic<int> ProcessRow ;
void f4()
{
for(int i=0;i<LOOPCNT;i++)
{
sem2.unlock() ;
++ProcessRow ;
}
cout << "i am out" << endl ;
}
void f5()
{
int icnt = 0 ;
std::chrono::milliseconds sleepDuration(1000);
while(1)
{
sem2.lock() ;
++icnt ;
std::this_thread::sleep_for(sleepDuration);
cout << ProcessRow << "in f5 " << endl ;
--ProcessRow ;
if(icnt >= LOOPCNT)
break ;
}
printf("(%d)\n",icnt) ;
}
输出:
i am out
10in f5
9in f5
8in f5
7in f5
6in f5
5in f5
4in f5
3in f5
2in f5
1in f5
(10)
看起来信号只有在 pthread_cond_wait 正在等待时才有效!!否则,信号丢失!!
对于 std::condition_variable ,看起来 std::condition_variable.wait() 会在调用 notify_one() 时唤醒,如果你在 10 秒前调用 notify_one() 然后调用 wait() ,std::condition_variable.wait() 仍然会收到 notify_one() 消息,与 pthread_cond_t 完全不同!!
我在这个测试中错过了什么吗?或者就像我的测试一样,std::condition 和 pthread_cond_t 就像测试显示的一样?
编辑:
我觉得下面这个测试会更容易一些,很抱歉忘记解锁导致测试失败,他们是一样的行为!!!!
int main()
{
//pthread_mutex_lock(&mutex);
++ProcessRow ;
pthread_cond_signal(&condA);
//pthread_mutex_unlock(&mutex);
printf("sending signal...\n") ;
sleep(10) ;
pthread_mutex_lock(&mutex);
while (ProcessRow <= 0)
pthread_cond_wait(&condA, &mutex);
pthread_mutex_unlock(&mutex);
printf("wait pass through\n") ;
}
这将显示:
sending signal...
wait pass through
对于 std::condition_variable
int main()
{
sem2.unlock() ;
std::chrono::milliseconds sleepDuration(10000);
cout << "going sleep" << endl ;
std::this_thread::sleep_for(sleepDuration);
sem2.lock() ;
cout << "lock pass through " << endl ;
}
将显示:
going sleep
lock pass through
所以测试错误是我的错,导致死锁!感谢您提供的所有宝贵建议!
最佳答案
在您的 pthread 代码中,您永远不会解锁互斥量,consumer()
函数会在第二次迭代时死锁。此外,外层的 while
循环应该在满足某些条件时中断。我建议它应该在 icnt
到达 LOOPCNT
时爆发。这种类型与您在 f5()
中打破循环的方式相匹配。
void *consumer(void *x)
{
int icnt = 0 ;
while(1)
{
pthread_mutex_lock(&mutex);
while (ProcessRow <= 0)
pthread_cond_wait(&condA, &mutex);
__sync_sub_and_fetch(&ProcessRow,1) ;
++icnt ;
printf("receving=(%d) icnt=(%d)\n",ProcessRow, icnt) ;
pthread_mutex_unlock(&mutex);
if (icnt == LOOPCNT) break;
usleep(10000) ;
}
printf("(%d)\n",ProcessRow) ;
}
您的代码的 std::thread
版本似乎与 pthread 版本完全不匹配,因此我认为您无法通过这种方式比较它们的执行情况。与其模仿信号量,不如像在代码的 pthread 版本中一样使用 std::condition_variable
更好。这样,您就可以真正将苹果与苹果进行比较。
std::condition_variable condA;
std::mutex mutex;
volatile int ProcessRow = 0 ;
#define LOOPCNT 10
void producer()
{
int idx ;
for(idx=0;idx<LOOPCNT;idx++)
{
std::unique_lock<std::mutex> lock(mutex);
__sync_add_and_fetch(&ProcessRow,1) ;
condA.notify_one();
printf("sending signal...(%d)\n",ProcessRow) ;
}
printf("I am out ... \n") ;
}
void consumer()
{
int icnt = 0 ;
while(icnt < LOOPCNT)
{
if(icnt > 0) usleep(10000);
std::unique_lock<std::mutex> lock(mutex);
while (ProcessRow <= 0)
condA.wait(lock);
__sync_sub_and_fetch(&ProcessRow,1) ;
++icnt ;
printf("receving=(%d) icnt=(%d)\n",ProcessRow, icnt) ;
}
printf("(%d)\n",ProcessRow) ;
}
关于c++ - pthread_cond_t 和 std::condition_variable 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18222137/
我正在使用如下 map : 键--->任务ID 值 ---> pthread_cond_t 对象 当某个任务完成时,我会使用匹配的 pthread_cond_t 元素唤醒与其关联的所有 pthread
我正在尝试在 while 循环条件下检查类型为 pthread_cond_t 的变量的值。 变量在节点结构中定义,格式如下: pthread_cond_t cv; 当我尝试使用 != 或 == NUL
如果我有一段这样的代码 pthread_cond_t c; pthread_mutex_t m; int var = 0; void some_function(int *some_variable)
我在动态库中有一个逻辑,它运行主可执行文件请求的一些服务。 从库代码调用start_service 后,需要在服务就绪之前进行一些准备,在此期间,主代码不应尝试访问该服务。 为了在服务准备就绪时通知主
我使用 pthread_cond_t 向主线程发出子线程执行结束的信号。由于我没有同步对共享资源的访问,我想知道包含 pthread_cond_wait 的循环会是什么?这是我所拥有的: pthrea
我有两个类评估线程,但我无法将信号从一个线程发送到另一个线程,一些想法为什么它不起作用: 第 1 类: #include "timer.h" #include #include #include
我测试了两个非常简单的在多线程代码中打印偶数/奇数的示例,一个使用 pthread_cond_t 而另一个不使用。 void *even(void *arg) { while(count h
我最近在 C# 中看到了 EventWaitHandle 的强大行为,并决定在姊妹应用程序中移动一些功能来实现同样的功能。唯一的问题是姊妹应用是用 C 语言编写的。 没什么大不了的,我正在使用 pth
如果在线程代码中,我在 C 中创建了一个 pthread_cond_t c; 条件变量或互斥锁 pthread_mutex_t m;,建议在所有工作完成后销毁它们完成了。 为什么会这样? 另外,如果
将 pthread_mutex_t 和 pthread_cond_t 作为类成员静态变量有什么缺点吗? class myclass { public: stati
我最近正在测试std::condition_variable,测试后发现它与pthread_cond_t有很大的不同,我想知道我的测试是否有错误?还是 std::condition_variable
根据 Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008, 当至少一个线程正在等待这个条件变量时,不应在 pthread_cond
我写了一个程序,但它没有像我预期的那样工作。我有两个线程:thread 触发 func 和 anotherThread 触发 anotherFunc。我想做的是当 cont 在 func 中达到值 1
有: 一个条件变量“var”:var的值只能是0或1; 一个提供者线程“thP”:当从网络接收到数据时,设置 var 1(可用); 一个消费者线程“thC”:wait() for var。当得到var
最近我将我的操作系统从 RHEL 7.6(gcc 4.8.5) 升级到 RHEL 8.4(gcc 8.4),但我正面临与使用 pthread_mutex_t 的进程同步相关的问题和 pthread_c
我是一名优秀的程序员,十分优秀!