gpt4 book ai didi

c - Linux 中的 C 线程同步

转载 作者:太空宇宙 更新时间:2023-11-04 10:55:11 24 4
gpt4 key购买 nike

我在同步线程时遇到问题,因此每个线程可以先运行一个作业,然后另一个线程启动同一个作业,依此类推。下面是我的代码:

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>

void handler ( void *ptr );
sem_t mutex;

int worker = 2; // number of workers
int job = 4; // number of jobs for each worker

int main()
{

int i = 0;
pthread_t thread_a;

sem_init(&mutex, 0, 1);

for (i; i < worker; i++)
{
int *n_workers = malloc(sizeof(*n_workers));
*n_workers = i;
pthread_create (&thread_a, NULL, (void *) &handler, n_workers);
}

pthread_join(thread_a, NULL);

sem_destroy(&mutex);

pthread_exit(0);
}

void handler ( void *ptr )
{
int x = *((int *) ptr);
int i = 0;

for (i; i < job; i++)
{
sem_wait(&mutex);
printf("Worker %d: Doing Job %d\n", x, i);
sem_post(&mutex);
}
}

输出是:

Worker 1: Doing Job 0
Worker 1: Doing Job 1
Worker 1: Doing Job 2
Worker 1: Doing Job 3
Worker 0: Doing Job 0
Worker 0: Doing Job 1
Worker 0: Doing Job 2
Worker 0: Doing Job 3

程序中,每个 worker 有4个工作岗位,共有2个 worker 。问题是 worker 1 一次完成所有 4 个工作,而 worker 0 在它之后完成所有工作。理想的输出是这样的:

Worker 0: Doing Job 0
Worker 1: Doing Job 0
Worker 0: Doing Job 1
Worker 1: Doing Job 1
Worker 0: Doing Job 2
Worker 1: Doing Job 2
Worker 0: Doing Job 3
Worker 1: Doing Job 3

我不确定问题出在哪里,非常感谢任何帮助。谢谢

最佳答案

如果你想确保每个线程在作业 [n+1] 之前执行作业 [n],你需要使用 barriers ,通过使用信号量(为此您可能需要咨询 The Little Book of Semaphores )或使用 pthread_barrier_t 实现它们。

如果您选择后者,您应该能够通过对代码进行最少的修改来实现效果:

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>

void handler ( void *ptr );
pthread_barrier_t barrier;

int worker = 2; // number of workers
int job = 4; // number of jobs for each worker

int main()
{

int i = 0;
pthread_t thread_a;

pthread_barrier_init(&barrier, NULL, worker);

for (i; i < worker; i++)
{
int *n_workers = malloc(sizeof(*n_workers));
*n_workers = i;
pthread_create (&thread_a, NULL, (void *) &handler, n_workers);
}

pthread_join(thread_a, NULL);

pthread_barrier_destroy(&barrier);

pthread_exit(0);
}

void handler ( void *ptr )
{
int x = *((int *) ptr);
int i = 0;

for (i; i < job; i++)
{
printf("Worker %d: Doing Job %d\n", x, i);
pthread_barrier_wait(&barrier);
}
}

这样,每个作业 [n] 都会在作业 [n+1] 开始之前执行 int worker = 2 次。工作人员在 job[n] 上工作的顺序无关紧要,因此您可能会得到不同的输出,例如:

Worker 0: Doing Job 0
Worker 1: Doing Job 0
Worker 1: Doing Job 1
Worker 0: Doing Job 1
Worker 0: Doing Job 2
Worker 1: Doing Job 2
Worker 0: Doing Job 3
Worker 1: Doing Job 3

重要的是最右边的列。

关于c - Linux 中的 C 线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29103608/

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