Остановить поток, только если запущено n потоков, включая самого себя - PullRequest
0 голосов
/ 03 мая 2020

Мне предлагается создать несколько потоков в процессе (48), но поток номер 14 должен остановиться, только если запущено 6 потоков, включая самого себя. Однако они вводят бесконечный l oop.

Вот функция, которую должны выполнять мои потоки из процесса:

pthread_mutex_lock_t lock;
pthread_mutex_cond_t cond;
reached_6_threads = false;
    void *thread_function_P6(void *args)
    {
        th *t = (th *)args;
        printf("started thread %d", t->id);
        if (t->id != 14)
        {
            pthread_mutex_lock(&lock);
            while (th_no > 6)
            {
                    pthread_cond_wait(&cond, &lock);
            }
            if(!reached_6_threads && th_no==6){
                pthread_cond_wait(&cond, &lock);
                th_no--;
                reached_6_threads = true;
            }
            th_no++;
            if (!reached_6_threads && th_no == 6)
            {
                pthread_cond_broadcast(&cond);
                pthread_mutex_unlock(&lock);
            }
        }
        printf("threads running: %d\n", th_no);
        printf("stopped thread %d", t->id);
        pthread_exit(0);
    }

lock и cond инициализируются перед созданием потоков.

1 Ответ

1 голос
/ 03 мая 2020

Я не уверен, что понимаю вас, но обратите внимание, что в вашем коде:

a) Большая часть кода находится под блокировкой мьютекса, что означает, что они не могут работать параллельно

b) Поток 14 запускается независимо от количества запущенных потоков

В любом случае причина его зависания:

a) Ваши потоки запускаются почти последовательно

b) Потоки 1-5 пропускают while и оба if, th_no теперь равен 5 (при условии, что он был инициализирован до 0?)

c) Поток 6 поднимает th_no до 6 и входит в секунду, если, выполняя трансляцию, но нет потоки, застрявшие в этой блокировке условия

d) Потоки 7 и выше вводятся первыми, если и ожидают блокировку условия, которая никогда не сломается

Я бы предложил следующее решение. Поскольку я не полностью вас понял, в этом примере разрешено запускать только 6 потоков независимо от их идентификатора, и вам придется внести только незначительные изменения.

pthread_mutex_lock(&lock); 
while(th_no >= 6){pthread_cond_wait(&cond, &lock);}
th_no++;
pthread_mutex_unlock(&lock); //Raise counter and unlock the mutex

/*
Thread function code here. Pay attention to critical code and use mutex.
*/

pthread_mutex_lock(&lock); //Acquire lock once again, decrease counter and broadcast if number of threads is ok now
th_no--;
if(th_no <= 5){
   if(pthread_cond_broadcast(&cond)){
       // Error as it should return 0 on success
   }
}
pthread_mutex_lock(&unlock);

Дайте мне знать, если это поможет

...