Threadpool如何在C中创建一个带队列的线程池?

时间:2015-06-20 16:45:19

标签: c multithreading pthreads queue jobs

所以我有以下内容:

具有“作业”的队列“q”每个作业都是一个字符('1' - '6')。 我正在尝试创建一个5线程数组来处理这个队列,所以当一个线程完成它的任务时,它会从que中获取另一个。

例如队列是:

q ='3','4','3','3','5','3','4','3','3','5','3',' 4' , '3', '3', '5', '3', '4', '3', '3', '5'

所以我很难解决这个问题。任何帮助都会非常感谢你!

这是我到目前为止所得到的:

int internal_count = 0;
pthread_t threads[5];
Queue que; // simple char queue (its working)
void createThreads(int numOfThreads) {
    for (int i = 0; i < numOfThreads; i++) {
            pthread_t tid;
            threads[i] = pthread_create(&tid, NULL, start_thread, (void*) que);
            if (threads[i] != 0) { /* error handling */ }
    }
}

我不知道为什么它还没有在这种方法中运行..

void* start_thread(void* arg) {
    char job;
    int fd;
    int x = random_number(10, 100); // its working
    struct timespec tim, tim2;
    pthread_t ptid;
    char *message;
    while (que.size == 0) {

    }
     pthread_mutex_lock(&lock);
    // ADD MUTEX!!!!!!!!!!!!!
    job = que.Dequeue();

    switch(job) {
    case '1':
        // go to sleep
        tim.tv_sec  = 0;
        tim.tv_nsec = x * 1000000L;
        nanosleep(&tim , &tim2);
        internal_count++;
        break;
    case '2':
        // go to sleep
        tim.tv_sec  = 0;
        tim.tv_nsec = x * 1000000L;
        nanosleep(&tim , &tim2);
        internal_count += 2;
        break;
    case '3':
        // go to sleep
        tim.tv_sec  = 0;
        tim.tv_nsec = x * 1000000L;
        nanosleep(&tim , &tim2);
        internal_count += 3;
        break;
    case '4':
        // go to sleep
        tim.tv_sec  = 0;
        tim.tv_nsec = x * 1000000L;
        nanosleep(&tim , &tim2);
        internal_count += 4;
        break;
    case '5':
        // go to sleep
        tim.tv_sec  = 0;
        tim.tv_nsec = x * 1000000L;
        nanosleep(&tim , &tim2);
        internal_count += 5;
        break;
    case '6':
        ptid = pthread_self();
        message = fromIntToString((int) ptid);
        strcat(message, ",");
        strcat(message, fromIntToString(internal_count));
        strcat(message, "\n");
        break;
    default:break;
    }
    pthread_mutex_unlock(&lock);
    return NULL;

}

2 个答案:

答案 0 :(得分:0)

一个可能的原因,很难确定,因为你没有完整的代码,是你的main函数在创建所有线程后立即返回,因此你的进程在线程获得之前退出真的做任何事。如果您希望主线程等待所有线程完成,那么在创建一堆线程后,您会看到pthread_join,这取决于您的应用程序。快速检查这是否是您的问题(这不是一个好的解决方案只是一种检查方法)是在您的结尾放置一个while(1);(注意分号) main所以它不会退出,只是旋转等待,以便你的其他线程有机会运行。

此外,通常只有在将作业元素出列时才锁定互斥锁,而不是在处理它时。这样,在线程处理作业时,另一个线程可以从队列中删除一些东西。当然,除非处理作业需要访问其他一些全局数据,否则您可能希望对该全局数据进行不同的锁定。这可能与您没有看到线程运行的原因无关。

答案 1 :(得分:0)

您尚未发布完整代码,但根据现有问题快速记录:

  • 检查您是否正确初始化pthread互斥锁。看看pthread_mutex_init或PTHREAD_MUTEX_INITIALIZER

  • 您仅将锁定对象用于队列操作。但是,除非您以原子方式管理队列,否则您还需要一个关键队列大小功能的临界区。

  • 关于为什么你的线程函数没有运行,你必须深入了解更多,看看你的线程是否没有启动,或者他们不能继续前进。您可以通过在线程函数内设置断点来轻松完成此操作。同样在GDB中,您可以使用&#34; info threads&#34;看到创建的主题。

  • 我没有使用while循环来检查任务是否提交到队列,我强烈建议你使用条件变量,因为它们是你正在做的事情的内置同步原语。

    < / LI>

这篇文章是用C ++编写的,它使用了C ++ 11线程库,但它提供了有关条件变量以及如何实现线程安全队列的很好的信息,因为这是实现线程池所需要知道的:

Implementing a thread safe queue using condition variables