Завершающая резьба в C - PullRequest
0 голосов
/ 08 марта 2020

Я учусь использовать поток в C, я создал программу, которая вызывает два потока и печатает что-то одновременно.

Вот мой код:

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

pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

void *functionCount1();
void *functionCount2();
int  count = 0;

#define COUNT_DONE  10

int main()
{
   pthread_t thread1, thread2;

   pthread_create( &thread1, NULL, &functionCount1, &count);
   pthread_create( &thread2, NULL, &functionCount2, &count);

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   printf("Final count: %d\n", count);

   exit(0);
}

//Print count when count is even
void *functionCount1()
{

        for(;;)
        {
                pthread_mutex_lock( &count_mutex );


                pthread_cond_wait( &condition_var, &count_mutex );
                        count++;
                        printf("Counter value functionEven: %d\n",count);

                pthread_mutex_unlock( &count_mutex );
        }
}

//Print count when count is odd
void *functionCount2(void *arg)
{
        for(;;)
        {
                pthread_mutex_lock( &count_mutex );
                        if(count%2 == 0)
                        {
                        pthread_cond_signal( &condition_var );
                        }
                        if(count % 2 != 0)
                        {
                        count++;
                        printf("Counter value functionOdd: %d\n",count);
                        }
                        pthread_mutex_unlock( &count_mutex );
                        if(count >= COUNT_DONE) return(NULL);
        }
}

Вот вывод, который я получил: enter image description here

Вывод правильный, но поток все еще работает в фоновом режиме. Как я могу исправить эту проблему и правильно завершить поток?

Ответы [ 2 ]

3 голосов
/ 08 марта 2020

functionCount1 не имеют условий для прекращения действия l oop. Он будет ждать, пока переменная условия будет сигнализирована после завершения functionCount2 навсегда.

2 голосов
/ 09 марта 2020

Кроме того, ожидающие условия также подвержены ложным пробуждениям, вы должны проверить предикат (если это действительно так) после пробуждения и go вернуться, чтобы дождаться, если это не так. Большинство UNIX систем разблокирует этот ожидающий вызов cond, в случае, если сигнал доставлен процессу, и они не будут перезапускать вызов, вы должны указать это в своем коде.

Подробнее об этом здесь

//Print count when count is even
 void *functionCount1()
 {

     for (;;) {
         pthread_mutex_lock(&count_mutex);

         pthread_cond_wait(&condition_var, &count_mutex);
         if(count >= COUNT_DONE)
             return NULL;
         count++;
         printf("Counter value functionEven: %d\n", count);

         pthread_mutex_unlock(&count_mutex);
     }
 }

 //Print count when count is odd
 void *functionCount2(void *arg)
 {
     for (;;) {
         pthread_mutex_lock(&count_mutex);
         if (count % 2 == 0) {
             pthread_cond_signal(&condition_var);
         }
         if (count % 2 != 0) {
             count++;
             printf("Counter value functionOdd: %d\n", count);
         }
         if (count >= COUNT_DONE) {
             pthread_cond_signal(&condition_var);
             pthread_mutex_unlock(&count_mutex);
             return NULL;
         }
         pthread_mutex_unlock(&count_mutex);
     }
 }

Код может быть лучше выражен, но надеюсь, что он передает необходимую вам информацию. Также необходимо добавить тест для предиката, который я не включил.

while (! (Предикат == true)) pthread_cond_wait (...);

...