Lon*_*Lin 2 c++ multithreading timer
我是多线程编程的新手,所以这个问题可能看起来有点傻,但我真的需要解决这个问题,所以我可以将它应用到我的项目中(这更复杂).跟随是我的代码,我试图让2个线程(父和子)更新相同的共享计时器,并在计时器达到特定限制时停止.但是当我编译并执行这段代码时,有两种不同的结果:1.子打印"由孩子在200000完成",但程序没有退出; 2.孩子打印"孩子在200000完成"并退出后,父母继续执行,打印几十行"父母做工作"和"父母在190000",然后打印"父母在200000完成"和程序退出正常.我想要的行为是更新计时器的任何线程,达到限制并退出,另一个线程应该停止执行并退出.我想我可能会在这里遗漏一些微不足道的东西,但我尝试过以多种方式更改代码,而我尝试过的任何东西似乎都没有用.任何帮助都感激不尽 :)
#include <iostream>
#include <unistd.h>
#include <mutex>
#include <time.h>
using namespace std;
mutex mtx;
int main () {
int rc;
volatile int done = 0;
clock_t start = clock();
volatile clock_t now;
rc = fork();
if (rc == 0) { //child
while (true) {
cout << "child doing work" << endl;
mtx.lock();
now = clock() - start;
if (done) {
mtx.unlock();
break;
}
if (now >= 200000 && !done) {
done = 1;
cout << "done by child at " << now << endl;
mtx.unlock();
break;
}
cout << "child at " << now << endl;
mtx.unlock();
}
_exit(0);
}
else { // parent
while (true) {
cout << "parent doing work" << endl;
mtx.lock();
now = clock() - start;
if (done) {
mtx.unlock();
break;
}
if (now >= 200000 && !done) {
done = 1;
cout << "done by parent at " << now << endl;
mtx.unlock();
break;
}
cout << "parent at " << now << endl;
mtx.unlock();
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
多进程
您的代码是多进程而不是多线程: fork()将通过复制调用进程来创建一个新的单独进程.
结果:在复制时,所有变量在两个进程中都包含相同的值.但是每个进程都有自己的副本,因此父进程中修改的变量不会在子地址空间中更新,反之亦然.
如果你想在进程之间共享变量,你应该看看这个SO问题
多线程
对于真正的多线程,你应该使用std::thread.忘记volatile,因为它不是线程安全的.请<atomic>改用,正如这部精彩视频中所解释的那样.
这是第一次尝试:
#include <iostream>
#include <mutex>
#include <thread>
#include <atomic>
#include <time.h>
using namespace std;
void child (atomic<int>& done, atomic<clock_t>& now, clock_t start)
{
while (!done) {
cout << "child doing work" << endl;
now = clock() - start;
if (now >= 2000 && !done) {
done = 1;
cout << "done by child at " << now << endl;
}
cout << "child at " << now << endl;
this_thread::yield();
}
}
void parent (atomic<int>& done, atomic<clock_t>& now, clock_t start)
{
while (!done) {
cout << "parent doing work" << endl;
now = clock() - start;
if (now >= 2000 && !done) {
done = 1;
cout << "done by parent at " << now << endl;
}
cout << "parent at " << now << endl;
this_thread::yield();
}
}
int main () {
atomic<int> done{0};
clock_t start = clock();
atomic<clock_t> now;
thread t(child, std::ref(done), std::ref(now), start); // attention, without ref, you get clones
parent (done, now, start);
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要使用互斥锁来保护原子访问,如果您愿意,lock_guard建议您使用互斥锁.
这个例子当然相当弱,因为如果你测试一个原子变量if if-condition,那么当输入if-block时它的值可能已经改变了.这不会在您的逻辑中导致"完成"意味着"完成"的问题.但是,如果你需要更加苛刻的方法,
compare_exchange_weak()或者compare_exchange_strong()可以进一步提供帮助.
| 归档时间: |
|
| 查看次数: |
1776 次 |
| 最近记录: |