C - 同步多个线程w / mutexs

时间:2016-03-04 23:29:18

标签: c multithreading pthreads mutex

我正在尝试同步多个(7)线程。我以为我理解它们是如何工作的,直到我在我的代码上尝试它并且我的线程仍在按顺序打印。这是代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = {4,6,3,1,5,0,2}; //Order in which to start threads
int num = 0;
pthread_mutex_t lock; //Mutex variable

int main()
{
    int i;
    pthread_t tid[7];

    //Check if mutex worked
    if (pthread_mutex_init(&lock, NULL) != 0){
        printf("Mutex init failed\n");
        return 1;
    }

    //Initialize random number generator
    time_t seconds;
    time(&seconds);
    srand((unsigned int) seconds);

    //Create our threads
    for (i=0; i<7; i++)
        pthread_create(&tid[i], NULL, text, (void*)code[i]);

    //Wait for threads to finish
    for (i=0; i<7; i++){
        if(pthread_join(tid[i], NULL)){
            printf("A thread failed to join\n");
        }
    }    
    //Destroy mutex
    pthread_mutex_destroy(&lock);

    //Exit main
    return 0;
}

void *text (void *arg)
{
    //pthread_mutex_lock(&lock); //lock

    long n = (long) arg;
    int rand_sec = rand() % (3 - 1 + 1) + 1; //Random num seconds to sleep
    while (num != n) {} //Busy wait used to wait for our turn
    num++; //Let next thread go
    sleep(rand_sec); //Sleep for random amount of time

    pthread_mutex_lock(&lock); //lock
    printf("This is thread %d.\n", n);

    pthread_mutex_unlock(&lock); //unlock
    //Exit thread
    pthread_exit(0);
}

所以在这里我试图让线程0-6打印IN ORDER但是现在它们仍然是乱码。注释掉的互斥锁是我最初使用它的地方,但后来将其移动到print语句上方的行,但我得到了类似的结果。我不确定我的互斥锁中的错误在哪里,有人可以给出一个提示或指向正确的方向吗?对此,我真的非常感激。提前谢谢!

1 个答案:

答案 0 :(得分:0)

您只能使用互斥锁使线程按顺序运行,因为它们以不可预测的顺序执行。 在我的方法中,我使用条件变量和共享整数变量来创建排队系统。每个线程都接受一个数字,当current_n数字等于实际线程之一时,它进入临界区并打印其数字。

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

#define N_THREAD 7

int current_n = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t number = PTHREAD_COND_INITIALIZER;


void *text (void *arg) {
   int i = (int)arg;

   pthread_mutex_lock(&mutex);
   while ( i > current_n ) {
      pthread_cond_wait(&number, &mutex);
   }

   //i = current_n at this point

   /*I use stderr because is not buffered and the output will be printed immediately.
     Alternatively you can use printf and then fflush(stdout).
   */
   fprintf(stderr, "I'm thread n=%d\n", i);
   current_n ++;

   pthread_cond_broadcast(&number);
   pthread_mutex_unlock(&mutex);
   return (void*)0;
}

int main() {
   pthread_t tid[N_THREAD];

   int i = 0;
   for(i = 0; i < N_THREAD; i++) {
      pthread_create(&tid[i], NULL, text, (void *)i);
   }

   for(i = 0; i < N_THREAD; i++) {
      if(pthread_join(tid[i], NULL)) {
        fprintf(stderr, "A thread failed to join\n");
      }
   }

   return 0;
}

输出结果为:

I'm thread n=0
I'm thread n=1
I'm thread n=2
I'm thread n=3 
I'm thread n=4
I'm thread n=5
I'm thread n=6

编译 gcc -Wall -Wextra -O2 test.c -o test -lpthread

不要担心警告。