如何仅使用 pthread 互斥体来同步多个线程?

问题描述 投票:0回答:1

我试图创建三个线程,每个线程打开一个不同的输入文件,从中读取单个字符并将其设置为全局变量,然后等待下一个线程从它打开的文件中读取单个字符并设置它到该全局变量,然后移动到下一个线程。

主要是,我打开了一个

file.out
来写入字符。所以 main 只会从全局变量中读取并按照 thread1、thread2、thread3、thread1、thread2、3..etc 读取的字符顺序写入
.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 %
我已经被困在这个问题上有一段时间了,我可能把它复杂化了,但不知道下一步该做什么。我真的很感激任何建议或提示。谢谢你。

c multithreading pthreads mutex
1个回答
0
投票
这是所需的一般逻辑:

线程 1、2 和 3:

    读取文件。
  1. 等轮到我写了。
  2. 写下数值。
  3. 离开专属区域
  4. 通知主线程是时候阅读了。
主线:

    对于 i = 1 到 3,
    1. 等有时间再看。
    2. 读取数值。
    3. 输出值。
    4. 发出信号,是时候写入下一个线程了。
我们实际上不需要任何互斥,因为一次只有一个线程可以写入。我们需要的是一个信号机制。互斥锁不是这样的。由于解锁 pthread 互斥锁的线程必须与锁定它的线程相同,因此我们需要使用类似的东西

while ( 1 ) { bool my_turn; pthread_mutex_lock( &mutex ); my_turn = turn == me; pthread_mutex_unlock( &mutex ); if ( my_turn ) break; }
这很糟糕,因为这是一个繁忙的等待循环。你需要某种信号机制(信号量、cond var 等)。

© www.soinside.com 2019 - 2024. All rights reserved.