使用 Mutex 和 Pthread 库的错误输出
Posted
技术标签:
【中文标题】使用 Mutex 和 Pthread 库的错误输出【英文标题】:Wrong Output using Mutex and Pthread Library 【发布时间】:2015-10-03 08:21:04 【问题描述】:以下程序的目的是学习 Mutex 和 Pthread 库。 main() 创建三个线程。 (线程 1、2 和 3)。 每个线程一个接一个地顺序,每个文件(不同的文件)读取一个字符并存储到全局常量中。 示例线程 1 从 file1 读取字符 'a',然后等待线程 2 和 3 相同(即分别从 file2 和 file3 读取 'b' 和 'c')。 读取完成后,我们希望 main 将全局常量打印到 file.out
我尝试过相同的程序,但输出不正确。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
char glob_var, strtemp[1024];
pthread_mutex_t lock;
int cnt = 0;
char inp[3][10] = "file-1.in", "file-2.in", "file-3.in";
void * thread_func(void * arg);
void * thread_func(void * arg)
FILE *fp;
char * argu = (char *)arg;
fp = fopen(argu, "r");
while (1)
pthread_mutex_lock(&lock);
glob_var = fgetc(fp);
if(feof(fp))
pthread_mutex_unlock(&lock);
break ;
if (glob_var != '\n')
strtemp[cnt++] = glob_var;
pthread_mutex_unlock(&lock);
fclose(fp);
return (void *)0;
int main(void)
FILE * fpout;
pthread_t threads[3];
int i = 0;
fpout = fopen("file.out", "w");
for (i = 0; i < 3; i++)
pthread_create(&threads[i], NULL, thread_func, (void *)inp[i]);
for (i = 0; i < 3; i++)
pthread_join(threads[i], NULL);
strtemp[cnt] = '\0';
cnt = 0;
while(1)
glob_var = strtemp[cnt++];
fprintf(fpout, "%c\n", glob_var);
if (strtemp[cnt] == '\0')
break;
fclose(fpout);
return 0;
Input File
File1 File2 File3
a u t
o . #
e p a
i r m
e n $
Output File
From Above Code Desired Output
t a
# u
r t
a o
m .
! #
$ e
s p
m a
u i
. r
p m
r e
n n
【问题讨论】:
您的互斥锁未正确初始化。 @EOF 虽然这是真的,但无论如何,互斥锁永远无法实现 OP 想要的...... 打开文件时,例如使用'fopen()',总是检查(!=NULL)返回值以确保操作成功 这一行:pthread_mutex_t lock;
应该是:pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
这一行:if(feof(fp))
的问题是 feof() 直到尝试准备好输入文件的末尾之后才为真。那是一次迭代为时已晚。建议:将该行和前一行替换为:if(EOF == (glob_var = fgetc(fp)))
【参考方案1】:
您的mutex
仅确保不超过一个线程同时访问您的全局变量。它不能保证线程的调度顺序。对于您想要做的事情,mutex
是错误的同步原语,因为它正是为此而设计的:排除其他线程同时访问同一资源。
你想明确地允许一个特定的线程在另一个线程之后。这可以使用semaphores
完成。每个线程需要一个。因此,在全局范围内声明第二个 sem_t
数组,其中包含 3 个条目,将第一个初始化为 1,其他初始化为 0。然后,将一个 线程号 (0 - 2) 传递给您的线程并执行一些操作喜欢:
int next = num + 1;
if (next > 2) next = 0;
sem_wait(sems[num]);
/* your code, accessing inp[num] */
sem_post(sems[next]);
【讨论】:
以上是关于使用 Mutex 和 Pthread 库的错误输出的主要内容,如果未能解决你的问题,请参考以下文章
pthread_join 和 pthread_mutex_lock 有啥区别?