这是一个问题,例如我需要执行x次执行某项操作的函数,但在任何给定时间只能执行四个线程。因此线程A,B,C,D可以分别启动任务0、1、2、3。但是,任务四要等到其中一个线程完成后才能开始,所以说如果线程A完成了,那么下一个任务可以由一个空闲线程执行。这应该重复x次,其中x是需要调用该函数的次数。
因此,我使用了信号量,并在完成后加入pthread以确保其完成。但是,有时主函数在某些线程完成之前完成执行,并且valgrind抱怨我的pthread_create泄漏内存。我认为我做的方式不正确或天真,因此,对解决该问题的任何指导或示例代码将不胜感激!这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
sem_t s;
typedef struct Data Data;
struct Data {
pthread_t* a;
int index;
int j;
};
void* someFunction(void* arg){
/* Only at most num_threads should be here at once; */
sem_wait(&s);
Data* d = arg;
printf("Successfully completed task %d with thread %d\n", d->index, d->j);
sleep(2);
pthread_t* z = d->a;
free(d);
pthread_join(*z, NULL);
sem_post(&s);
return 0;
}
int main(void){
int num_task = 15; // i need to call someFunction() 9000 times
int num_threads = 4;
int j = 0;
sem_init(&s, 0, num_threads);
pthread_t thread_ids[num_threads];
for (int i = 0; i < num_task; i ++){
/*NEED TO COMPLETE num_tasks using four threads;
4 threads can run someFunction() at the same time; so one all four are currently executing someFunction(), other threads can't enter until one has completed. */
if (j == num_threads){
j = 0; // j goes 0 1 2 3 0 1 2 3 ...
}
Data* a = malloc(sizeof(Data));
a->a = thread_ids + j;
a->index = i;
a->j = j;
sem_wait(&s);
pthread_create(thread_ids + j, NULL, someFunction, a);
sem_post(&s);
j ++;
}
return 0;
}
非常感谢
最佳答案
使线程彼此等待通常会很快变得混乱,并且您很可能最终会遇到线程尝试自行连接或从未连接的情况。
最多运行四个线程的最可靠方法是仅创建四个线程。
不必根据需要创建线程,而是让每个线程(潜在地)执行多个任务。
您可以将“任务”概念与“线程”概念分开:
为线程执行任务队列。
创建四个线程。
每个线程从队列中获取一个任务并执行任务,重复执行直到队列为空。
等待线程在main
中完成。
唯一需要同步的是从队列中删除任务,这非常简单。
(如果任务不是独立的,则需要更复杂的管道。)
伪代码(我对pthread不太熟悉,因此发明了一些名称):
typedef struct Task
{
/* whatever */
};
/* Very simplistic queue structure. */
typedef struct Queue
{
mutex lock;
int head;
Task tasks[num_tasks];
};
/* Return front of queue; NULL if empty. */
Task* dequeue(Queue* q)
{
Task* t = NULL;
lock_mutex(q->lock);
if (q->head < num_tasks)
{
t = &q->tasks[q->head];
q->head++;
}
unlock_mutex(q->lock);
return t;
}
/* The thread function is completely unaware of any multithreading
and can be used in a single-threaded program while debugging. */
void* process(void* arg)
{
Queue* queue = (Queue*) arg;
for (;;)
{
Task* t = dequeue(queue);
if (!t)
{
/* Done. */
return NULL;
}
/* Perform task t */
}
}
/* main is very simple - set up tasks, launch threads, wait for threads.
No signalling, no memory allocation. */
int main(void)
{
pthread threads[num_threads];
Queue q;
q.head = 0;
/* Fill in q.tasks... */
/* Initialise q.lock... */
for (int ti = 0; ti < num_threads; ti++)
{
pthread_create(threads + ti, NULL, process, &q);
}
for (int ti = 0; ti < num_threads; ti++)
{
/* join the thread */
}
return 0;
}
关于c - C pthread只允许四个线程执行功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37586657/