C программа застряла, не входит в основной () - PullRequest
0 голосов
/ 07 марта 2019

Я пытаюсь запустить программу, в которой один поток берет данные из стандартного ввода, а затем другой выводит их в стандартный вывод, ничего сложного, но когда я запускаю свою программу с /. Filename 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;
}

Ответы [ 2 ]

2 голосов
/ 07 марта 2019

У вас есть очевидная опечатка в вашем 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_precitanych, оценивающий 0

Дополнительное замечание, вы #define V 300, но вы делаете char a[300];, пока используете V в другом месте.Лучше сделать char a[V]; или использовать sizeof(a) в другом месте без определения V


Примеры выполнения после изменений:

/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
0 голосов
/ 07 марта 2019

Вы ничего не видите на терминале из-за опечатки в выводе printf("main/n");

printf не сброшено в stdout и созданные потоки потребляют цикл навсегда или, по крайней мере,в течение длительного времени.

Вы должны добавить fflush(stdout); после оператора printf, чтобы проверить это.

Затем вы можете попробовать printf("main\n"); без fflush(), чтобы убедиться, что stdout является буферизованной строкой, то есть: вывод выводится на терминал при выводе новой строки.

Если вы перенаправляете вывод в файл, stdout обычно полностью буферизуется, поэтому вам следует добавить явный fflush(stdout);после каждой операции вывода, чтобы вы могли видеть вывод в выходном файле на лету или после уничтожения программы.

Обратите внимание, что код будет легче читать для большинства пользователей здесь, если вы используете английские слова для идентификаторов, типы, комментарии и сообщения.

...