提问人:brocoli 提问时间:10/30/2023 更新时间:10/30/2023 访问量:61
如何仅使用 pthread 互斥锁同步多个线程?
How could I synchronize multiple threads with only the use of pthread mutexes?
问:
我试图制作三个线程,每个线程打开一个不同的输入文件,从中读取一个字符并将其设置为全局变量,然后等待下一个线程从它打开的文件中读取一个字符,并将其设置为该全局变量,然后移动到下一个线程。
总的来说,我打开了一个来写字符。因此,main 将只从全局变量中读取并按照 thread1、thread2、thread3、thread1、thread2、3..等读取的字符顺序写入文件。file.out
.out
这是我到目前为止所拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
//global char variables
char globalVAR1;
char globalVAR2;
char globalVAR3;
//define mutexes
pthread_mutex_t mutexOne;
pthread_mutex_t mutexTwo;
pthread_mutex_t mutexThree;
void *threadOne(void *arg){
FILE *fileOne;
fileOne = fopen("hw5-1.in", "r");
char mChr1;
//read each char
if(fileOne == NULL){
perror("file one error\n");
}
while(!feof(fileOne)){
fscanf(fileOne, "%c\n", &mChr1);
printf("char read: %c \n", mChr1);
pthread_mutex_lock(&mutexOne);
globalVAR1 = mChr1;
pthread_mutex_unlock(&mutexOne);
}
}
//thread two
void *threadTwo(void *arg){
FILE *fileTwo;
fileTwo = fopen("hw5-2.in", "r");
char mChr2;
//read each char
if(fileTwo == NULL){
perror("file two error\n");
}
while(!feof(fileTwo)){
fscanf(fileTwo, "%c\n", &mChr2);
printf("char read: %c \n", mChr2);
pthread_mutex_lock(&mutexTwo);
globalVAR2 = mChr2;
pthread_mutex_unlock(&mutexTwo);
}
}
//thread three
void *threadThree(void *arg){
FILE *fileThree;
fileThree = fopen("hw5-3.in", "r");
char mChr3;
//read each char
if(fileThree == NULL){
perror("file three error\n");
}
while(!feof(fileThree)){
fscanf(fileThree, "%c\n", &mChr3);
printf("char read: %c \n", mChr3);
pthread_mutex_lock(&mutexThree);
globalVAR3 = mChr3;
pthread_mutex_unlock(&mutexThree);
}
}
//main should open an out file for writing
int main(){
//open a file for writing
FILE *mainWriting;
mainWriting = fopen("hw5.out", "w");
FILE *count;
count = fopen("hw5-1.in", "r");
char cc;
int nu=0;
while(fscanf(count, "%c\n", &cc) == 1){
nu += 1;
}
rewind(count);
fclose(count);
//write the global value into the outfile
//the mutexes initialized
pthread_mutex_init(&mutexOne, NULL);
pthread_mutex_init(&mutexTwo, NULL);
pthread_mutex_init(&mutexThree, NULL);
pthread_t pthreadOne, pthreadTwo, pthreadThree;
pthread_create(&pthreadOne, NULL, threadOne, NULL);
pthread_create(&pthreadTwo, NULL, threadTwo, NULL);
pthread_create(&pthreadThree, NULL, threadThree, NULL);
while(nu != 0){
//write into hw5.out
pthread_mutex_lock(&mutexOne);
fputc(globalVAR1, mainWriting);
fputc('\n', mainWriting);
pthread_mutex_unlock(&mutexOne);
sleep(1);
pthread_mutex_lock(&mutexTwo);
fputc(globalVAR2, mainWriting);
fputc('\n', mainWriting);
pthread_mutex_unlock(&mutexTwo);
sleep(1);
pthread_mutex_lock(&mutexThree);
fputc(globalVAR3, mainWriting);
fputc('\n', mainWriting);
pthread_mutex_unlock(&mutexThree);
nu -=1;
}
sleep(1);
pthread_join(pthreadOne, NULL);
pthread_join(pthreadTwo, NULL);
pthread_join(pthreadThree, NULL);
fclose(mainWriting);
}
输入文件的行数相同,每行都有一个字符。
我的程序的输出预计为:
a
1
@
b
2
$
c
3
%
(输入文件实际上有点长。为简单起见,我没有包含整个输入文件。该程序应该处理任意长度的文件,假设它们都是相同的长度)
对于输入文件:
hw5-1.in
a
b
c
hw5-2.in
1
2
3
hw5-3.in
@
$
%
我只应该使用互斥锁来同步三个线程,而不使用标志、全局计数变量、信号量或条件。
我的输出是这样的:
c
3
%
c
3
%
c
3
%
我已经坚持了一段时间,我可能会把它弄得太复杂了,但不确定下一步该怎么做。我非常感谢任何建议或提示。谢谢。
答:
1赞
0___________
10/30/2023
#1
有 3 个互斥锁,它们将提供正确的读取器顺序。所有这些都由使用者线程锁定,并在它需要来自特定线程的数据时解锁。
另一个互斥锁保护全局变量。
共有 6 个互斥锁。3 表示正确的线程顺序,3 表示保护全局变量。
但是,仅使用互斥锁并不是实现它的最佳方式。
顺便说一句 您只能有一个全局变量。你不需要 3.
评论
0赞
brocoli
10/30/2023
这是否意味着两个不同的互斥锁将被解锁并锁定在每个线程的函数中,以获得正确的顺序?
下一个:使用条件变量的正确方法是什么?
评论