c – Parent不等待工作线程完成任务

c – Parent不等待工作线程完成任务,第1张

概述在我的程序中,主线程创建4个(或更多)工作线程.在某些时候,父(主线程)必须等待工人才能完成一些计算.线程在无限循环上运行,所以我不能使用pthread_join(..,..)POSIX函数来等待工作完成.所以我使用全局计数器和条件变量. 主线程代码 unsigned jobs = 0; // global variable// global mutex and cv. They get in 在我的程序中,主线程创建4个(或更多)工作线程.在某些时候,父(主线程)必须等待工人才能完成一些计算.线程在无限循环上运行,所以我不能使用pthread_join(..,..)POSIX函数来等待工作完成.所以我使用全局计数器和条件变量.

主线程代码

unsigned jobs = 0; // global variable// global mutex and cv. They get initialised in my main.pthread_mutex_t counter_mutex;pthread_cond_t  counter_cv;static voID process(..){    jobs = myArray.size();     // I am using a function here that broadcasts a cv in order to    // wake up the workers    pthread_mutex_lock(&counter_mutex); // lock counter        while (jobs > 0){            pthread_cond_wait(&counter_cv,&counter_mutex); // PARENT SHOulD GET STUCK HERE TILL WORKERS ARE DONE        }        // cout << "Workers are done" << endl;    pthread_mutex_unlock(&counter_mutex);   // unlock counter}

工人代码

extern unsigned jobs; extern pthread_mutex_t counter_mutex; extern pthread_cond_t  counter_cv; voID *run() {    for (int i = 0;; i++) {        // do some calculations here        pthread_mutex_lock(&counter_mutex); // lock counter            jobs--;            if (jobs == 0){                pthread_cond_signal(&counter_cv);                cout << "All jobs are done" << endl;            }        pthread_mutex_unlock(&counter_mutex);   // unlock counter    }}

问题是,有时我的主线程不会卡在条件变量中,以便等待工作者,这有时会导致分段错误.是否存在任何我无法看到的竞争条件并导致此问题?

解决方法 您的代码中存在明显的并发问题.为简单起见,假设我们有2名工人,还剩2个工作岗位.可能发生以下情况:

>作业计数设置为2
>父级卡在等待条件变量
>两个工人都在无限循环中开始处理迭代
>无论出于何种原因,第一个工作人员都会更快地完成任务,并执行锁定的作业计数更新.作业计数减少到1,因此父级等待并释放锁定.然后工作人员开始下一次迭代.不幸的是,实际上没有任何工作(1完成了,1当前由第二工人执行).但是它开始了一个假设的工作(可能解决了同时删除或超出范围的数组元素?)
>第二个工作完成其工作,并将作业计数减少到0,导致父级被唤醒,持有锁,退出循环并解锁.
>你注意到,虽然父母认为它已经结束了,但是第一个工作人员仍在处理一个假设的任务,可能试图访问myArray,而它会被清理,或者其他任何可能出错的地方.

因此,您有两次比赛和/或segfalts的机会:在父级和仍然活跃的工作者中,忙于一项不存在的任务.

我认为如果你开始循环获取锁定,检查是否还有剩余的工作,并且预先减少作业数量,那么工作循环会更安全,这样同伴工作人员就会知道真正剩下的东西:

voID *run() {    for (int i = 0;; i++) {        pthread_mutex_lock(&counter_mutex); // lock counter            if (jobs == 0){                pthread_cond_signal(&counter_cv);                cout << "All jobs are done" << endl;            }            else jobs--;        pthread_mutex_unlock(&counter_mutex);   // unlock counter        // do some calculations here    }}

优点是工人只有在真正留下工作的情况下才能工作.唯一的麻烦就是父母被第一个失业的工人唤醒了.然而,其他工人仍然可以跑步.

如果这是一个问题,你可以例如维护一个仍然活动的作业的计数器,并使父循环打开(作业> 0 || active_jobs> 0)

总结

以上是内存溢出为你收集整理的c – Parent不等待工作线程完成任务全部内容,希望文章能够帮你解决c – Parent不等待工作线程完成任务所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1224678.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存