Я новичок в потоках и семафорах, и я могу понять, почему мой код не работает, любая помощь будет оценена - PullRequest
0 голосов

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

Я также пытался pthread_join, но это то же самое: он не будет печатать, несмотря ни на что.

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <semaphore.h>

sem_t f1, f2, f3;

int done = 1;

void *threadfunc(void *n) {
    int a = 0;

    while (1) {
        if ((int)*(int *)n == 1) {
            //printf("1st THREAD!\n");
            printf("<ONE>");
            sem_wait(&f1);
        } else if ((int)*(int *)n == 2) {
            //printf("2st THREAD!\n");
            printf("<TWO>");
            sem_wait(&f2);
        } else {
            //printf("3st THREAD!\n");
            printf("<THREE>");
            sem_wait(&f3);
        }

        //}

        if (done == 3) {
            done = 1;
            sem_post(&f1);
        } else if (done == 1) {
            done = 2;
            sem_post(&f2);
        } else if (done == 2) {
            done = 3;
            sem_post(&f3);
        }
    }
}

int main() {
    pthread_t tid1, tid2, tid3;
    int n1 = 1, n2 = 2, n3 = 3;

    for (;;) {
        // Create 3 threads
        pthread_create(&tid1, NULL, threadfunc, (void *)&n1);
        sleep(1);

        pthread_create(&tid2, NULL, threadfunc, (void *)&n2);
        sleep(1);

        pthread_create(&tid3, NULL, threadfunc, (void *)&n3);
        sleep(1);

        // infinite loop to avoid exit of a program/process
    }

    return 0;
}

Ожидаемый результат: ONE TWO THREE ONE TWO THREE и т. Д. .

Фактический вывод: нет

1 Ответ

2 голосов
/ 15 июня 2019

У вас есть несколько проблем в вашем коде:

  • Вы запускаете не только три потока, но и неограниченное их количество.Комментарий в вашем коде предполагает, что смысл этого может состоять в том, чтобы предотвратить выход основного потока, но это совершенно неуместный способ решения проблемы.Обычный подход заключается в pthread_join() ваших потоках, или, может быть, просто в sigsuspend() или pause().

  • Вы используете свои семафоры без их инициализации.В результате поведение всех ваших функций семафора не определено.Вы должны использовать sem_init() в начале программы, чтобы инициализировать состояние каждого семафора, включая, но не ограничиваясь, его начальное значение.Вероятно, один из них должен быть инициализирован значением 1, а другие - значением 0.

  • Структура вашей функции потока странная.Обычно одно ожидание ожидания семафора сначала , затем выполнить любую работу, а затем опубликовать следующий семафор последним.Но даже если вы упорядочите семафорные операции так, как вы это делаете, я не вижу смысла в переменной done.Ваше использование этого полностью избыточно с использованием n.Они передают одну и ту же информацию: идентификатор потока.

  • Если вы хотите, чтобы данные, напечатанные каждым потоком, появлялись немедленно, то вам следует fflush(stdout) после каждого вызова printf().

  • Если вы хотите задержку между отпечатками, вы должны поместить ее в функцию нити, а не в main().

...