Onur94
Onur94

Reputation: 51

Pthread: wake a thread from 4 threads

I have a problem with waking a thread in C++. I have 4 running threads. I want to wake my sleeping thread when the 4 running threads are completed. I did it with condition wait operation but it doesn't look good. How can I do this process in a better quality way?

4 tasks are triggered by broadcast and starts working on different cores at the same time. At the end of each task, it sets the flag of its own taskID to 1 and sends a signal to the sleeping task. The task in sleep state wakes up every time it receives a signal and checks the flag of each task. If the 4 task flag is 1, it continues and does its own work.

void *thread_sleep( void *arg )
{
    pthread_mutex_lock(&mutex_sleep);
    
    while(flag_task[0] == 0 || flag_task[1] == 0 || flag_task[2] == 0 || flag_task[3] == 0)
        pthread_cond_wait(&cond_sleep, &mutex_sleep);
    
    /*
        .
        .
        .
        .   
    */
        
    flag_task[0] = 0;
    flag_task[1] = 0;
    flag_task[2] = 0;
    flag_task[3] = 0;
    
    pthread_mutex_unlock(&mutex_sleep);
}


void *thread( void *arg)
{
    int taskID = *(char *)arg - '0';

    while(1)
    {
        pthread_mutex_lock(&mutex[taskID]);
        pthread_cond_wait(&cond, &mutex[taskID]);
        /*
            .
            .
            .
            .
        */
        pthread_mutex_unlock(&mutex[taskID]);
        flag_task[taskID] = 1;
        pthread_cond_signal(&cond_sleep);
    }
}

int main()
{
    pthread_create( &pthread1, NULL, thread, (void *)"0" );
    pthread_create( &pthread2, NULL, thread, (void *)"1" );
    pthread_create( &pthread3, NULL, thread, (void *)"2" );
    pthread_create( &pthread4, NULL, thread, (void *)"3" );
    pthread_create( &pthread5, NULL, thread_sleep, (void *)"4" );
    
    pthread_cond_broadcast(&cond);
}

Upvotes: 2

Views: 54

Answers (1)

Onur94
Onur94

Reputation: 51

I solved using barrier. Thank you @Quimby.

void *thread_sleep( void *arg )
{
    pthread_mutex_lock(&mutex_sleep);
    pthread_cond_wait(&cond_sleep, &mutex_sleep);
    /*
        .
        .
        .
        .   
    */ 
    pthread_mutex_unlock(&mutex_sleep);
}


void *thread( void *arg)
{
    int taskID = *(char *)arg - '0';

    while(1)
    {
        pthread_mutex_lock(&mutex[taskID]);
        pthread_cond_wait(&cond, &mutex[taskID]);
        /*
            .
            .
            .
            .
        */
        pthread_mutex_unlock(&mutex[taskID]);
        pthread_barrier_wait(&barrier);
        pthread_cond_signal(&cond_sleep);
    }
}

int main()
{
    pthread_barrier_init(&barrier, NULL, 4);
    
    pthread_create( &pthread1, NULL, thread, (void *)"0" );
    pthread_create( &pthread2, NULL, thread, (void *)"1" );
    pthread_create( &pthread3, NULL, thread, (void *)"2" );
    pthread_create( &pthread4, NULL, thread, (void *)"3" );
    pthread_create( &pthread5, NULL, thread_sleep, (void *)"4" );
    
    sleep(1);
    pthread_cond_broadcast(&cond);
}

Upvotes: 1

Related Questions