为什么空的 while 循环与包含某些内容的 while 循环的反应不同?
Why an empty while loop don't react the same as a while loop with something in it?
我目前有 2 个 pthreads 正在运行,我想等待其中一个线程结束,以便我的程序继续。
在我的线程中,我有一个变量,它可以是真或假(它是一个全局变量(。创建线程后(一个要求输入 cin 和一个等待 10 秒,如果达到 10 秒,它会杀死"cin"线程并结束自己,如果检测到 cin ","cin"线程会杀死"计时器"线程(我希望我的程序等待。当每个线程结束时,他们将变量"stoptimer"设置为true。
首先在创建线程后,我开始编写这样的while循环:
while(stoptimer==false){}
线程启动,我们进入 while 循环,但即使线程结束并且"停止计时器"变为 true,我们也不会退出循环。
我目前正在这样做:
rc = pthread_create(&threads[1], NULL, Timer, (void *)&td[1]);
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
rc = pthread_create(&threads[2], NULL, Choix, (void *)&i);
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
while (stoptimer==false) {
cout<<"wait"<<endl;
}
在这里,您可以看到我正在创建线程,然后进入包含某些内容的 while 循环。如果我保持这个循环原样,它正在做我想做的事情,当计时器结束或用户输入值时,我们会退出 while,因为"stoptimer"不再为假。但我不希望这个库特在这里。
我尝试在循环中放置一个注释,以便它不为空,但它仍然反应为空。在我的理解中,如果它适用于计数,那么现在它应该可以工作,但什么都不做。
为什么要这样做? 空而循环有什么特别之处吗?
这里的问题是您在没有任何形式的线程同步的情况下读取stoptimer
变量,我怀疑您在没有任何线程同步的情况下写入它。
为了保证一个线程所做的更改在另一个线程上可见,您必须使用某种形式的线程同步,或者依赖于了解底层 CPU 的内存模型(弱或强(,这通常看起来很容易,但在最好的时候可能很难做到正确。
查看您的代码,我怀疑使用条件变量跨线程同步会更明智。
问题不在于 while 循环。问题是您有一个未定义行为的竞争条件。具体来说,不允许同时从不同的线程读取和写入变量(R/R 可以,R/W 和 W/W 不能(。编译器可以通过在寄存器中缓存stoptimer
的值并从寄存器而不是变量读取来自由"优化"while循环。因此,它不会确定值已更改。允许编译器执行此操作,因为在 while-循环中读取时stoptimer
更改是非法的。
要解决此问题,您需要在读取和写入共享变量之前锁定互斥锁。所以你会做这样的事情:
while(true){
pthread_mutex_lock(stoptimer_mutex);
auto ts = stoptimer;
pthread_mutex_unlock(stoptimer_mutex);
if (ts==false)
break;
}
现在这真的很长而且很乏味,您真的不想每次访问stoptimer
时都这样做。要摆脱所有手动锁定,您可以使用隐式锁定和解锁的atomic<bool> stoptimer
,异常安全且更高效。但这仍然不好,因为你有一个忙碌的等待。现在您(希望(放弃了 pthreads,我们可以使用标准库函数进行线程创建。
std::promise one_thread_done;
auto one_thread_future = one_thread_done.get_future();
std::thread timer_thread{Timer, td[1]}; //create threads
std::thread choix_thread{Choix, i};
one_thread_future.wait(); //wait until one of them is done
在每个线程函数中,你one_thread_done.set_value();
发出信号,表明它已经在 try/catch 中完成,因为如果它已经被另一个线程设置,它会抛出一个future_error
。
future
的优点是它们易于使用和理解。缺点是它们仅使用 1 次,没有重置future
s。如果您需要反复等待其中一个线程,您将需要一个条件变量。
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- while循环中while循环的时间复杂度是多少
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 擦除while循环中迭代的元素
- 为什么我不能在 while 循环中创建线程?
- 退出简单while循环时出现问题
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 嵌套While循环不起作用(C++问题)
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 使用 GMP 的 while 循环出现问题
- 程序以使用 C++ 中的 while 循环查找一组数字的最小值
- 为什么在 while 循环中返回表达式不起作用
- 如何使用 do while 循环确定最高值和最低值
- 如何读取单个字符并在输入两个字符序列时输出? 使用 while 循环和C++
- 用于在 C++ 中使用 while 循环查找下一个素数的简单函数
- OpenCV QT,显示视频的帧(不使用while循环)
- 在 while 循环中使用 pow() 函数 C++
- C++ 制作/命名不初始化的向量(在 while 循环中)
- std::getline没有在while循环中重新请求用户输入