C-使用mutex同步多线程

C-使用mutex同步多线程,c,multithreading,pthreads,mutex,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}; //Ord

我正在尝试同步多(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);
}
#包括
#包括
#包括
#包括
#包括
void*文本(void*arg);
长码[]={4,6,3,1,5,0,2}//启动线程的顺序
int num=0;
pthread_mutex_t lock//互斥变量
int main()
{
int i;
pthread_t tid[7];
//检查互斥锁是否工作
if(pthread\u mutex\u init(&lock,NULL)!=0){
printf(“互斥初始化失败\n”);
返回1;
}
//初始化随机数生成器
时间t秒;
时间(秒);
srand((无符号整数)秒);
//创建我们的线程

对于(i=0;i而言,您无法使线程仅以互斥体的顺序运行,因为它们以不可预测的顺序执行。 在我的方法中,我使用一个条件变量和一个共享整数变量来创建一个排队系统。每个线程取一个数字,当
当前\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;
}
编译
gcc-Wall-Wextra-O2测试.c-o测试-lpthread


不要担心警告。

请解释为什么您认为线程应该“按顺序”打印?您所做的只是在printf()周围加上一个锁,它仍然有自己的内部锁。@据我所知,在当前线程完成之前,该锁将限制其他线程执行任何操作。@donutjuice:那么您理解不正确。(成功)锁定互斥锁将阻止其他线程获取它,直到您释放它,仅此而已。与“直到当前线程完成”无关。由于您在尝试获取互斥锁之前让所有线程都随机休眠一段时间,因此即使忽略无法预测线程运行顺序这一事实,您也会想方设法让它们不按顺序运行。您对互斥锁所做的任何事都无法阻止或试图阻止这种情况。@PaulGriffiths你能告诉我应该如何使用互斥锁吗?我试着把锁放在函数的顶部(注释掉的lock语句)但是当我这样做时,没有打印线程。@donutjuice:互斥体用于同步对共享资源的访问,而不是同步线程的执行。您根本不应该将它们用于此目的。互斥体应该保护对
num
的访问。您可以使用条件变量同步线程的执行布尔斯。
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