gpt4 book ai didi

C pthread只允许四个线程执行函数

转载 作者:行者123 更新时间:2023-11-30 19:12:14 25 4
gpt4 key购买 nike

这里有一个问题,假设我需要执行一个函数 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 pthread只允许四个线程执行函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37586657/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com