C pthread : Multiple Threads but only ONE thread is used

标签 c multithreading pthreads

我正在研究生产者和消费者问题。我创建了一个生产者来将内容放入有界缓冲区中,并使用多个消费者从缓冲区中获取数据。为了检查每个消费者是否在工作,我给他们每个人一个 ID 并让他们打印出来。

以下是创建多个消费者的代码。

#define CONSUMER_NUM 5;
pthread_t consumer[CONSUMER_NUM];
for(i=0;i<CONSUMER_NUM;i++){
    int t = i;
    pthread_create(&consumer[i],NULL,fun_consumer,(void*)&t);   
}   // pass i to the function fun_consumer to be an id of the thread

我期望的可能是这样的:

Consumer 1
Consumer 2
Consumer 3
Consumer 4
Consumer 5

我知道由于线程的随机执行,输出通常不会像这样。我在这里期望的是大多数消费者将开始工作。然而,事实是打印出来的程序是这样的:

Consumer 5
Consumer 5
Consumer 5
Consumer 5
Consumer 5

这里只用了一个消费者。我试过“ sleep ”,它可以给我预期但导致执行缓慢的输出。我想知道是否有更好的方法来解决这个问题?

最佳答案

您为每个线程提供了一个指向局部变量 i 的指针。随着每次循环迭代,i 都在变化 - 到线程实际启动和就绪循环完成时,i 等于 5(最后一个值)。

然而,这只是众多潜在结果之一。您的线程 ID 确实可以读取任何内容,因为您在此代码中有一个经典的数据竞争。您正在从多个线程访问一个变量,该变量不受任何保护。如果运气好的话,甚至可以读到 42。

解决方案。 为每个线程动态创建一个新变量并传递该变量的地址(您需要在线程中删除以防止内存泄漏),或者将整数变量转换为指针并将该值提供给线程。要(某种程度上)以可移植的方式执行此操作,您的 i 实际上应该是 uintptr_t 类型,而不是 unsigned int

如何每次都创建新变量的示例:

for (i=0 ; i<CONSUMER_NUM; ++i) {
    int* id = malloc(sizeof(int));
    *id = i;
    pthread_create(&consumer[i],NULL,fun_consumer, id);   
}
...
void* fun_consumer(void* arg) {
    int id = *(int*)(arg);
    free(arg)
    // rest of code

关于C pthread : Multiple Threads but only ONE thread is used,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36437064/

相关文章:

c - Recv() 不在单独的线程中工作,C 套接字编程

c - pthread_join() 中的段错误

c - 获取c函数的手册页而不是系统命令

c - dup 和 dup2 命令

Java Locale对象作用域是线程还是应用程序?

c - 不采用else分支的多线程代码

c - Linux 中对 pthread_create 的 undefined reference

c - 超几何分布的 C 代码优化

c - 将输入的数据存储在数组中

java - 在单个套接字上发送和接收多个请求和响应(多线程)