Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当条件或子线程退出时退出主线程_C_Multithreading_Pthreads - Fatal编程技术网

C 当条件或子线程退出时退出主线程

C 当条件或子线程退出时退出主线程,c,multithreading,pthreads,C,Multithreading,Pthreads,我的C程序由两个线程组成,由主线程启动。程序启动时,main使用pthread_create创建两个线程。这些线程th1和th2对全局int变量S执行一些求和/减法运算 根据特定条件,th1和th2可能在某个点退出 主线程启动th1和th2,然后根据需要等待和退出 条件:S达到大于一个数字的值 th1和th2均退出 无论先出现什么条件,main都将退出并打印出S。写入main的退出条件的正确方法是什么 注意这是一个大学练习,因此解决方案应该合理简单,并且基于有限的一组C库,包括pthread.h

我的C程序由两个线程组成,由主线程启动。程序启动时,main使用pthread_create创建两个线程。这些线程th1和th2对全局int变量S执行一些求和/减法运算

根据特定条件,th1和th2可能在某个点退出

主线程启动th1和th2,然后根据需要等待和退出

条件:S达到大于一个数字的值 th1和th2均退出 无论先出现什么条件,main都将退出并打印出S。写入main的退出条件的正确方法是什么

注意这是一个大学练习,因此解决方案应该合理简单,并且基于有限的一组C库,包括pthread.h

我无法在th1和th2上使用pthread_join,因为在子线程退出之前,该数字可能会超过阈值条件1。如果子线程不再运行,有没有办法签入主线程

我的解决方案主要使用pthread条件。条件的逻辑检查是正在运行的线程数和整数比较。当创建线程时,我通过增加线程计数器来注册它。当它退出时,我注销它。所有更改都包装在互斥对象中

int main() {
  pthread_t th1, th2;
  pthread_mutex_init(&mutex, NULL);
  pthread_cond_init(&run, NULL);
  srand(time(NULL));
  int ret;

  // ...

  if (pthread_create(&th1, NULL, alpha, NULL) == 0) {
    thread_register();
  }
  if (pthread_create(&th2, NULL, beta, NULL) == 0) {
    thread_register();
  }

  for (;;) {
    pthread_mutex_lock(&mutex);
    while(threads > 0 && S < 1000) {
      pthread_cond_wait(&run, &mutex);
    }
    pthread_cancel(th1);
    pthread_cancel(th2);
    break;
    pthread_mutex_unlock(&mutex);
  }

  // ...
}
子线程在关闭或更改主线程时发送pthread_cond_信号以唤醒主线程


这样,每次main唤醒时,它都可以检查子线程是否消失了threads==0或S。我看到的唯一错误是for循环将完成的唯一一件事是跳过pthread\u mutex\u unlock调用,这可能不是您想要的,但也可能不重要,因为您即将退出流程。你看到问题/不良行为了吗?谢谢,这是个好电话。中断是在一次小的重构后添加的,我没有注意到。你的反馈绝对有道理。@BrianMcFarland不,该计划按预期运行。这感觉很复杂,因为我必须引入所有信号/等待调用来同步进程。我感到惊讶的是,合理的简单程序可能需要这样的实现工作,例如手动注册/取消注册线程等。如果可以保证两个操作都是原子的,那么线程注册/计数部分可以简化为两个递减操作。如果使用C11/C++11或更高版本,则此atomic_fetch_add/atomic_fetch_sub具有语言std功能。如果使用较旧版本的语言,则可以使用编译器内置功能,例如GCC的_sync_fetch_和_add@BrianMcFarland请随时发布您的评论作为回复,以便我可以接受。