如何按此顺序执行3个线程?

时间:2017-11-20 00:02:24

标签: c pthreads thread-synchronization

我遇到了问题。我已经尝试了几天在C中按此顺序执行3个线程: 线程1 线程3 线程1 线程2 线程1

我使用条件变量。这是我的代码,只需打印:

线程1 线程3

它会被阻止

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

struct node{
int val;
};

void * function(void *);
int turn = 1,var = 3;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond  = PTHREAD_COND_INITIALIZER;


int main(){

int i;
pthread_t *pidthreads = NULL;

struct node *data;


pidthreads = (pthread_t *) calloc(3, sizeof(pthread_t));
pthread_mutex_lock(&mutex);
for(i=1; i<=3; i++){
    data = (struct node*)malloc(sizeof(struct node));
    data->val = i;
    pthread_create(&pidthreads[i], NULL, function, (void*)data);
    printf("Thread [%u] has been created\n", (unsigned int)pidthreads[i]);
    }
    pthread_mutex_unlock(&mutex);

    for(i=1; i<=3; i++)
    pthread_join(pidthreads[i], NULL);

return 0;
}

void * function( void *arg){
int myturn = ((struct node *)arg)->val;

pthread_mutex_lock(&mutex);
while(turn != myturn) pthread_cond_wait(&cond, &mutex);

printf("Thread %d\t[%u]\n", myturn, (unsigned int)pthread_self());

if(turn == 1){
    turn=var;
    var--;
}else{
    if(turn == 3){
        turn = 1;
    }else{
        if(turn == 2){
            turn = 1;
        }
    }
}

pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);

}

我真的不知道该怎么做。我感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

在你的函数中添加一个循环。

int myturn = ((struct node *)arg)->val;

while(true){ // add loop

    pthread_mutex_lock(&mutex);
    while(turn != myturn) pthread_cond_wait(&cond, &mutex);
    ....
    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&mutex);
}

但你必须添加离开的条件。

while(true){

    pthread_mutex_lock(&mutex);
    // conditions to leave the waitting loop
    while(turn != myturn && turn!=0) pthread_cond_wait(&cond, &mutex);

    if(turn==0) { // conditions to leave the infinite loop
        pthread_mutex_unlock(&mutex);
        break;
    }
    printf("Thread %d\t[%u]\n", myturn, (unsigned int)pthread_self());
    ...
    pthread_mutex_unlock(&mutex);
}