c - C Pthread:同时只运行10个线程(这里有什么问题)
问题描述
所以我对 C 中 pthread 的整个概念非常陌生,但请听我说。我有以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t endCond = PTHREAD_COND_INITIALIZER;
static pthread_cond_t startCond = PTHREAD_COND_INITIALIZER;
void * threadThingy(void * n){
pthread_cond_wait(&startCond, &mutex);
printf("%d: RAND: %d\n", *((int*)n), rand());
//Lock mutex before broadcasting to main thread
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&endCond);
pthread_mutex_unlock(&mutex);
free(n);
fflush(stdout);
return 0;
}
int main(void){
printf("Starting\n");
pthread_t threads[100];
int i = 0;
while(i < 10){
int *arg = malloc(sizeof(int));
*arg = i;
pthread_create(&threads[i], NULL, threadThingy, arg);
i++;
}
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&startCond);
int finished = 0;
while(finished <= 100){
pthread_cond_wait(&endCond, &mutex);
//Lock mutex so no other requests can come in
pthread_mutex_lock(&mutex);
finished++;
int *arg = malloc(sizeof(int));
*arg = 11;
pthread_create(threads[i], NULL, threadThingy, arg);
i++;
pthread_cond_broadcast(&startCond);
pthread_mutex_unlock(&mutex);
}
printf("Stopping\n");
sleep(1000);
}
整个目标是同时运行 100 个线程中的(仅)10 个线程。我的想法是启动 10 个线程,而不是等到一个线程完成并启动另一个线程。所以我让程序等到一个线程返回,然后我启动一个新线程,以便替换刚刚返回的线程。我错过了什么?因为现在我只把它作为输出:
起始 0:兰德:1804289383
解决方案
正如 Lavigne958 所提到的,在函数 threadThingy() 中存在由 pthread_cond_wait() 导致的死锁,因为它将获取锁。同样,您正试图将其锁定在下一行。这导致死锁。
有几点需要检查:
您需要在调用 pthread_cond_wait() 之前锁定互斥锁。
如果您解决了上述问题,使用具有相同互斥锁的多个条件变量可能会导致进一步的死锁。
如果您不加入线程,最好使用 PTHREAD_CREATE_DETACHED 属性创建分离线程。
N个线程同时运行的问题可以用一个信号量或一个条件变量(和一个互斥锁)来解决。下面给出了带有信号量的示例。
#include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> sem_t mysem; #define NUM_CONCURRENT_THREADS 4 #define MAX_THREADS 40 void *thread(void *arg) { printf("Thread id %ld: started\n", pthread_self()); sleep(5); // Do some work printf("Thread id %ld: Exiting\n", pthread_self()); sem_post(&mysem); return NULL; } int main() { pthread_t t[MAX_THREADS]; pthread_attr_t attr; int rc, i = 0; sem_init(&mysem, 0, NUM_CONCURRENT_THREADS); rc = pthread_attr_init(&attr); rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); printf("\nParent begin\n"); while(i < MAX_THREADS) { sem_wait(&mysem); pthread_create(&t[i], &attr, thread, NULL); i++; } printf("\nParent end.\n"); sem_destroy(&mysem); return 0; }
有关线程的更多信息,请查看博客Tech Easy。
推荐阅读
- c - 有没有办法找到可变大小格式化浮点
- java - Cup-carbon 新功能创建中的问题
- sql - Codeigniter 从声明的变量发布数据
- python - 我们可以在 python 中作为 POST 请求发送的有效负载的最大大小是多少
- css - 如何在反应钩子useEffect中添加自定义css
- python - 如果文本包含在另一个数据框中,则使用二进制指定标记行
- django - 应用程序的 Django 日志记录配置
- gitlab - 如何在单个降价文件中包含植物图?
- nginx - 当主机标头中的域与请求 url 中的域不匹配时,如何防止 nginx 上的重定向?
- python - 测试时是否可以在 django runserver 内运行 celery 任务?