在 C 语言的跨平台线程池库中高效处理作业队列和线程信号

问题描述 投票:0回答:1

我正在尝试用 c 语言制作一个跨平台线程池库。 我不明白的是,例如,如果我在线程池中有 4 个线程,并且我给所有 4 个线程分配工作,那么如果我添加 20 个作业,则需要很长时间(在本例中为 1 分钟)在 1 分钟标记之前进入作业队列,当线程将任何内容添加到队列中时,所有 20 个函数调用都会向线程发出信号,但没有线程能够获取该信号(因为没有线程正在等待任何信号)。并且信号会丢失。当任何线程空闲时,它们将无限期地等待,因为所有作业都已在队列中,因此不再有信号。

这是示例代码

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

volatile int job[10];
volatile int job_counter = 0;
pthread_mutex_t job_mutex;
pthread_cond_t job_cond;

void *worker_func(void *arg) {
    while (1) {
        pthread_mutex_lock(&job_mutex);
        pthread_cond_wait(&job_cond, &job_mutex);
        printf("here2\n");
        printf("work doing %d\n", job[job_counter]);
        sleep(3);
        if(job_counter++==10){
            break;
        }
        pthread_mutex_unlock(&job_mutex);
    }
}

int main() {
    pthread_t thread;
    pthread_cond_init(&job_cond, NULL);
    pthread_mutex_init(&job_mutex, NULL);
    pthread_create(&thread, NULL, worker_func, NULL);
    printf("here1\n");
    sleep(2);
    for (int i = 0; i < 10; i++) {
        pthread_mutex_lock(&job_mutex);
        job[i]=i;
        pthread_cond_signal(&job_cond);
        pthread_mutex_unlock(&job_mutex);
    }
    sleep(2);
    printf("here3\n");
    pthread_join(thread, NULL);
}

如果您想了解我的问题的具体情况和根源,请看这里
https://github.com/Pithikos/C-Thread-Pool/issues/132
任何帮助将不胜感激。

c multithreading synchronization signals wait
1个回答
0
投票

当线程将任何内容添加到队列中时,所有 20 个函数调用都会向线程发出信号,但没有线程能够获取该信号(因为没有线程正在等待任何信号)。而且信号会丢失。

您错误地使用了条件变量(或计划这样做)。

条件变量必须始终与可测试谓词(条件)相关联,该谓词必须为真,线程才能继续通过给定点。 例如“任务队列不为空”。 到达该点的线程首先在互斥量的保护下评估谓词。 仅当谓词评估为 false 时,它才会等待 CV。 此外,从等待返回后,线程必须循环回来并再次测试条件是否满足,然后可能返回等待。

是的,可能没有线程在提交后立即准备好运行新任务,因此可能没有线程被 CV 的信号唤醒。 但这并不能阻止任务被执行,因为接收信号只是告诉线程它们可能需要注意相关状态更改的一种方式,例如任务已添加到队列中。 它本身不应该是您的线程了解有工作要做的方式。

© www.soinside.com 2019 - 2024. All rights reserved.