Программа Pthreads с мьютексом - каждый раз печатает одну и ту же строку - PullRequest
0 голосов
/ 15 июня 2019

У меня есть школьный проект, который требует, чтобы я написал программу, которая печатает это: <ONE><TWO><THREE><ONE><TWO><THREE><ONE><TWO><THREE>….............., используя 3 потока и мьютекс. Я пытался сделать это с помощью класса, но он просто печатает только <ONE>. Вы можете помочь мне решить мою проблему и понять, что я не так?

#include <pthread.h>
#include <stdio.h>

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *func(void *arg)
{
    pthread_mutex_lock(&mutex);
    while (1) {
        printf ("<ONE>");
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

void *func2(void *arg)
{
    pthread_mutex_lock(&mutex);
    while (1) {
        printf ("<TWO>");
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

void *func3(void *arg)
{
    pthread_mutex_lock(&mutex);
    while (1) {
        printf ("<THREE>");
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

main()

{
    pthread_t mythread1,mythread2,mythread3;

    pthread_create( &mythread1, NULL, func, (void *) 1);
    pthread_create( &mythread2, NULL, func2, (void *) 2);
    pthread_create( &mythread3, NULL, func3, (void *) 3);

    pthread_join ( mythread1, NULL);
    pthread_join ( mythread2, NULL);
    pthread_join ( mythread3, NULL);

    exit(0);
}

1 Ответ

1 голос
/ 15 июня 2019

Как я пояснил в комментариях, это застрянет в бесконечном цикле, потому что вы делаете блокировку и разблокировку вне цикла. Первый шаг - переместить их внутрь.

void *func(void *arg)
{
    while (1) {
        pthread_mutex_lock(&mutex);
        printf ("<ONE>");
        pthread_mutex_unlock(&mutex);
   }
   pthread_exit(NULL);
}

Далее нам нужно добавить синхронизацию. Самый простой способ сделать это - объявить глобальную переменную:

int next = 1; 

Затем мы модифицируем функцию следующим образом:

void *func(void *arg)
{
    while (1) {
        while(1) {
            pthread_mutex_lock(&mutex);
            if(next == 1) break;
            pthread_mutex_unlock(&mutex);
        }

        printf ("<ONE>");

        next = 2;

        pthread_mutex_unlock(&mutex);
   }
   pthread_exit(NULL);
}

В func2 и func3 необходимо изменить if(next == 1) и next = 2 до соответствующих значений. func2 должно иметь 2 и 3, а func3 должно иметь 3 и 1.

Этот метод называется занятым ожиданием и часто не является лучшим выбором, поскольку он довольно интенсивен. Лучшей альтернативой было бы заглянуть в pthread_cond_wait(). Вы можете прочитать об этом здесь: http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html

...