gpt4 book ai didi

c - C 中的信号量和线程

转载 作者:行者123 更新时间:2023-11-30 17:43:26 32 4
gpt4 key购买 nike

程序应采用3个文件名作为参数,创建2个线程,第一个线程从第一个文件读取,第二个线程从第二个文件读取,并且它们都写入第三个文件。最终,他们应该交替将正在读取的文件中的每一行写入第三个文件。当我运行程序时,它们并没有真正交替;有时,一个线程将其所有行写入文件,然后另一个线程将其所有行写入文件。有时,它们每条线交替,然后一条线一对,然后另一条线交替。有人可以指出我的写入方向,让每个线程交替写入文件吗?我发现当我更改 sem_init 函数的第三个参数时,它会影响线程交替的方式。

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>


#define BADFILE 2
#define BADPARAM 3
#define DEBUG 1

sem_t mutex;

typedef struct {
char *file;
FILE *mf;
} read_args;

void error(char *msg, int code)
{
fprintf(stderr, "Error: %s\nAborting.\n", msg);
exit(code);
}

void *readFile1(void *p)
{

read_args *param = (read_args *)p;
FILE *f1;
char *line;
size_t len = 0;
ssize_t read;
int lineCount = 1;
f1 = fopen(param->file, "r");
if(f1 == NULL)
{
error("File not found.", BADFILE);
}


while((read = getline(&line, &len, f1)) != -1)
{
sem_wait(&mutex);
fprintf(param->mf,"%s: %d: %s", param->file, lineCount,line);

#if DEBUG
printf("%s: %d: %s", param->file, lineCount,line);
#endif

sem_post(&mutex);
lineCount++;
}
fclose(f1);
pthread_exit(NULL);
}

void *readFile2(void *p)
{

read_args *param = (read_args *)p;
FILE *f1;
char *line;
size_t len = 0;
ssize_t read;
int lineCount = 1;
f1 = fopen(param->file, "r");
if(f1 == NULL)
{
error("File not found.", BADFILE);
}
//sem_wait(&mutex);
while((read = getline(&line, &len, f1)) != -1)
{
sem_wait(&mutex);
fprintf(param->mf,"%s: %d: %s", param->file, lineCount,line);

#if DEBUG
printf("%s: %d: %s", param->file, lineCount,line);
#endif

sem_post(&mutex);
lineCount++;
}

fclose(f1);
pthread_exit(NULL);
}


int main(int argc, char **argv)
{
FILE *f;
char *mergedfile;
pthread_t tid1, tid2;
read_args *p1;
read_args *p2;
p1 = malloc(sizeof(read_args));
p2 = malloc(sizeof(read_args));
if(argc != 4)
{
error("Invalid parameters. Proper use: ./merge <file1> <file2>"
" <mergedfile>", BADPARAM);
}

p1->file = argv[1];
p2->file = argv[2];

mergedfile = argv[3];
f = fopen(mergedfile, "w");
if(f == NULL)
{
error("Can't open file.", BADFILE);
}
p1->mf = f;
p2->mf = f;

sem_init(&mutex, 0, 3);
if(pthread_create(&tid1, NULL, readFile1, (void*)p1) < 0)
{
error("Can't create first thread", EXIT_FAILURE);
}
if(pthread_create(&tid2, NULL, readFile2, (void*)p2) < 0)
{
error("Can't create second thread", EXIT_FAILURE);
}
if(pthread_join(tid1, NULL) < 0)
{
error("Can't join first thread", EXIT_FAILURE);
}
if(pthread_join(tid2, NULL) < 0)
{
error("Can't join second thread", EXIT_FAILURE);
}
sem_destroy(&mutex);

fclose(f);
return(EXIT_SUCCESS);

}

最佳答案

您将信号量用作互斥锁。这将保持一个线程写入,而另一个线程阻塞,但无法保证执行顺序。正如您发现的那样,同一个线程可以连续多次获取信号量。每个线程都需要向对方发出信号,表明轮到它们了。他们通过发帖来做到这一点。

如果您使用第二个信号量,您可以强制线程交替。线程 1 需要等待互斥体 1 并发送到互斥体 2。线程 2 等待互斥体 2 并将其发送到互斥体 1。 Mutex1 需要初始化为 1,这样它才能先执行; mutex2 被初始化为 0,因此它必须等到 thread1 首先运行并发布才能执行任何操作。确保在 pthread_exit 之前发布到另一个线程的互斥锁,否则另一个线程可能有更多内容要读取,但会陷入死锁。

您还应该将 lineCount 的增量放在临界区中,因为它在线程之间共享。

关于c - C 中的信号量和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20233737/

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