如何通知工作线程有一些工作要完成?

How to signal the worker threads that there is some work to be finished?

我正在构建一个小型套接字服务器,我想在其中创建一个线程池,然后在 boss-worker 线程模式下工作。因此,每当主(老板)收到请求时,它就会从池中传递到其中一个工作线程。

在下面的代码片段中,我尝试创建 10 个线程。

void* process_data(void* arg) {
    printf("invoked by the created thread");
    while(1) {
          // sleep until woken
          // get item from queue
          // do something
    }
}

int total_threads_to_create = 10;
int total_created = 0;
while(total_created < 10) {
   // create 10 threads
   pthread_t thread;
   int created = pthread_create(&thread, NULL, process_data, NULL);
   if(created == 0) total_created++;
}

while(1) {
   // server accepts the request in an infinite loop
   int socket_fd = accept(ss_fd, (struct sockaddr*)&client_sock,&client_sock_len);

   put_new_request_in_queue();
   // signal to one of the thread that work is available

}

正如您在上面看到的,每个新线程都直接调用 process_data 方法。现在我想让 process_data 中的线程休眠直到被主线程唤醒。

我如何:

正常的解决方案是一个条件变量和一个队列。这里的一般模式称为 producer/consumer 模式。

你用互斥量保护队列,然后使用条件变量唤醒工作人员

制作人:

workToDo = generateSomeWork()
acquire mutex
queue.push(workToDo)
cv.notify();
release mutex

消费者:

loop:
    acquire mutex
    while queue empty
        wait on cv (releasing mutex while waiting)
    workToDo = queue.pop()
    release mutex
    do(workToDo)

就我个人而言,我还喜欢添加一个布尔标志 done,当所有工作人员都需要清理时将其设置为 True。因此,当你想干净地退出程序时,你获取互斥锁,将 done 设置为 true,然后在 cv 上广播,这会唤醒所有的工作。他们看到 done 已设置,并干净地终止。

You have a Producer-Consumer, use a semaphore

You have written an example of the "Producer-Consumer Problem".

The most appropriate control mechanism for managing a producer-consumer queue is to use a semaphore.

You also need to lock the shared queue

However, as you have multiple producers, you will also need a mutex to ensure that no two producer threads attempt to write into the output queue at the same time (if you don't, you will corrupt your queue data structure).

The Wikipedia article for Producer-Consumer contains an outline solution for you, but doesn't use the exact same function-names as the pthreads library you're using.

Pthreads semaphore implementation

The pthreads library implements semaphores through the sem_t type and sem_wait() ("wait") and sem_post() ("signal") calls.