首页 文章

限制并发线程的数量(使用pthreads)

提问于
浏览
4

我必须编写一个使用CURL在Web上发布信息的C应用程序 . 应用程序最多必须并行运行N(比如说10个)请求 . 我如何等待任何线程完成,而不是使用 pthread_join() 的特定线程 .

我读到了关于pthread_cond_wait的内容,但大多数示例都是控制线程(main)如何唤醒工作线程 . 我需要恰恰相反 - 工作线程必须能够在退出之前发出信号/唤醒父线程 .

Update: 实际上我需要一种方法来使管理器线程处于休眠状态,当工作线程完成它时_1041203不管线程是否结束并且将为作业创建新线程还是将使用线程池 . Threre仍然需要一种向管理者发出工作完成信号的方式 .

I hope that I DON'T get this suggestion

while(asleep){
  for(i = 0; i< threadCount; i++){
    pthread_mutex_lock(mutex);
    if(threads[i] == IDLE_STATE)
      startNewJob();
    pthread_mutex_unlock(mutex);
    usleep(100*1000);
  }
}

3 回答

  • 1

    条件变量就是你所追求的 . 它们可以很容易地用来从工作线程发出管理器线程的信号,反之亦然 .

    最后你的稻草人示例实际上非常类似于使用条件变量可以做的事情:

    pthread_mutex_lock(&mutex);
    while (!finished) {
      for(i = 0; i < threadCount; i++) {
        if(threads[i] == IDLE_STATE)
          startNewJob(i);
      }
    
      /* Not finished, and no idle threads, so wait */
      if (!finished)
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);
    

    线程完成后,它只会:

    pthread_mutex_lock(&mutex);
    threads[self] = IDLE_STATE;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    
  • 4

    而不是按需创建/销毁线程,在启动时创建10个工作线程池并让主程序向它们提供作业会更容易 .

    在启动时,您将创建一个包含10个工作程序的数组 . 这些可能看起来像

    typedef struct worker
    {
        pthread_t       thread;
        pthread_cond_t  cond;
        pthread_mutex_t mutex;
        struct job*     job;
        int             quit;
    } worker;
    

    管理员将通过设置他们的 job 成员然后向工作人员发送信号来依次将作业委托给每个线程 .

    每个工作人员都会循环,直到 quit 非零,等待其状态发出信号 . 在每个信号之后,它会在报告结果之前读取/处理其 job ,然后再次等待其条件 .

    Edit: 这里的're not keen on thread pools. You could instead try giving each thread a unique id; store some mapping between ids and other properties of each thread in the manager. When each thread completes, have it add its id to a list owned by the manager then signal a condition in the manager. Each time the manager wakes, it can pull the head from the list, lookup the appropriate thread, read back its job results then join the thread. Note that the manager'列表将被多个线程访问,因此读/写需要由互斥锁保护 .

    Edit2: 你'd like to know more about conditions and don't找到你的例子've found helpful. I'我不确定这个'll be any better but here' s some code I've written . OsSemaphore* 函数将条件包装到一个简单的Wait / Signal API中 .

  • 1

    你想要一个条件变量,你一直在看的相同的功能,但只是转过身来 . 你正在等待的条件是“ Worker 线程完成了一些工作” .

    主线程:

    • 锁定互斥锁
      没有线程完成时

    • :pthread_cond_wait

    • 解锁互斥锁

    • 安排工作

    • 循环

    每个工作线程在完成工作时都会:

    • 锁定互斥锁

    • 标记完成

    • pthread_cond_signal

    • 解锁互斥锁

    • 退出或等待工作

相关问题