【问题标题】:Wrong Output using Mutex and Pthread Library使用 Mutex 和 Pthread 库的错误输出
【发布时间】: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))) {

标签: c multithreading pthreads mutex


【解决方案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]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2018-10-03
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多