0

我正在尝试运行一个程序,其中一个线程从标准输入中获取数据,然后另一个线程在标准输出上提供数据,没什么太复杂的,但是当我使用/.filename < test.in > test.out运行我的程序时什么都不做。当我使用gcc -pthread filename.c -o filename -W -Wall 编译它时,似乎没有错误或警告。有人可以解释吗?同样在文件 test.out 中没有显示任何内容,而在 test.in 中是一个简单的句子。这是程序

#define V  300

pthread_cond_t cond;
pthread_mutex_t mutex;
char a[300];
int p = 0;
int w = 0;


void *thread1() {

    while(1){
        pthread_mutex_lock(&mutex);
        printf("thread1");
        while(p >0){
            pthread_cond_wait(&cond, &mutex);
        }

        p = fread(a, sizeof(char), V ,stdin);

        if(p == 0){
            pthread_exit(NULL);
        }
        if(p <= V){ 
            pthread_cond_signal(&cond);
        }
        pthread_mutex_unlock(&mutex);
    }

}

void *thread2() {
    while(1){
        pthread_mutex_lock(&mutex);
        printf("thread2");

        while(w >0){
            pthread_cond_wait(&cond, &mutex);
        }

        w = fwrite(a, sizeof(char),p, stdout);

        if(w == 0){
            pthread_exit(NULL);
        }
        if(w <= V ){ 
            pthread_cond_signal(&cond);
        }
        pthread_mutex_unlock(&mutex);
    }
}

int main (void) {
    printf("main/n");
    fflush(stdout);
    pthread_t t1, t2; 

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init (&cond, NULL);

    pthread_create(&t1, NULL, vlakno1,  NULL);
    pthread_create(&t2, NULL, vlakno2,  NULL);


    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}
4

2 回答 2

2

您的printf("main/n");而不是printf("main\n");(或只是puts("main");)中有明显的错字,但这是一个细节,而不是您的程序永远不会完成的原因

vlakno1中,您创建了一个死锁:

    if(poc_precitanych == 0){
        pthread_exit(NULL);
    }

因为你不解锁互斥锁,必须是

    if(poc_precitanych == 0){
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }

你在vlakno2有同样的问题:

    if(pocet_pisanych == 0){
        pthread_exit(NULL);
    }

一定是

    if(pocet_pisanych == 0){
        pthread_mutex_unlock(&mutex);
        pthread_exit(NULL);
    }

以下也很奇怪:

    pocet_pisanych = fwrite(a, sizeof(char),poc_precitanych, stdout);

    if(pocet_pisanych == 0){
        pthread_exit(NULL);
    }

即使不是不可能,也很难在没有成功的情况下在stdou上进行写入。因此,您退出该循环的唯一机会就是将值设为poc_precitanych0

补充说明一下,您在其他地方使用V#define V 300时会这样做。最好在不定义 V的情况下做或在别处使用char a[300];char a[V];sizeof(a)


更改后的执行示例:

/tmp % ./a.out < /dev/null
main
vlakno 1vlakno 2

没有什么可读取poc_precitanych的,所以值为 0 并且两个线程完成,但是

/tmp % echo "1 2 3" | ./a.out
main
vlakno 1vlakno 1vlakno 21 2 3
^C
于 2019-03-07T08:38:00.413 回答
0

由于输入错误,您在终端上看不到任何内容printf("main/n");

printf的输出不会被刷新到stdout并且创建的线程永远消耗循环,或者至少在很长一段时间内。

您应该fflush(stdout);printf声明之后添加以验证这一点。

然后你可以尝试printf("main\n");fflush()验证是否stdout是行缓冲的,即:当输出换行符时,输出被刷新到终端。

如果将输出重定向到文件,stdout通常是完全缓冲的,因此您应该fflush(stdout);在每个输出操作之后添加一个显式,以便您可以在运行中或在终止程序后看到输出文件中的输出。

请注意,如果您在标识符、类型、评论和消息中使用英文单词,则此处的代码对于大多数用户来说会更容易阅读。

于 2019-03-07T08:31:30.393 回答