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

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

Я заглянул в pthread_join (), но похоже, что он ждет, пока поток завершит работу, а это не то, что я хочу.

2
user7673022 2 Ноя 2018 в 23:49

1 ответ

Лучший ответ

Вы можете использовать барьеры.

Из раздела «Барьеры pthread» в руководстве randu.org по pthread:

Потоки pthreads могут участвовать в барьере для синхронизации в определенный момент времени. Объекты-барьеры инициализируются как мьютексы или условные переменные, за исключением одного дополнительного параметра count. Переменная count определяет количество потоков, которые должны присоединиться к барьеру, чтобы барьер достиг завершения и разблокировал все потоки, ожидающие на барьере.

Другими словами, вы можете создать барьер с помощью n, и любые потоки, вызывающие pthread_barrier_wait, будут ждать, пока не будут выполнены вызовы n к pthread_barrier_wait.

Ниже приведен простой пример, в котором все три потока будут печатать «До» перед печатью любой потоком «После».

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

pthread_barrier_t barrier; 

void* foo(void* msg) {
    printf("%s: before\n", (char*)msg);

    // No thread will move on until all three threads have reached this point
    pthread_barrier_wait(&barrier);

    printf("%s: after\n", (char*)msg);
}

int main() {

    // Declare three threads
    int count = 3;
    pthread_t person_A, person_B, elevator;

    // Create a barrier that waits for three threads
    pthread_barrier_init(&barrier, NULL, count); 

    // Create three threads
    pthread_create(&person_A, NULL, foo, "personA");
    pthread_create(&person_B, NULL, foo, "personB");
    pthread_create(&elevator, NULL, foo, "elevator");

    pthread_join(person_A, NULL);
    pthread_join(person_B, NULL);
    pthread_join(elevator, NULL);
    printf("end\n");
}

Запустите код здесь

3
Increasingly Idiotic 2 Ноя 2018 в 22:20