线程同步之互斥锁

互斥锁是我们用来解决线程同步的一种常用方法,它的头文件在#include

1.互斥锁的创建

pthread_mutex_t mutex;

2.创建完成之后需要初始化

pthread_mutex_init(
            pthread_mutex_t* mutex;
            const pthread_mutexattr_t attr;  //一般传NULL
            );

3.用完之后需要销毁锁

pthread_mutex_destroy(pthread_mutex_t *mutex);

4.加锁

pthread_mutex_lock(pthread_mutex_t* mutex);
        mutex没有被上锁,当前线程会将这把锁锁上,如果被锁上了,当前线程被阻塞;锁被打开之后,线程解除阻塞

5.尝试加锁

pthread_mutex_trylock(pthread_mutex_t*mutex)
       没有锁上:当前线程会给这把锁加锁;如果锁上了,不会阻塞,也可以执行其他操作
                if(pthread_mutex_trylock(&mutex) == 0)
                {
                    //尝试加锁,并且成功,访问共享资源
                }
                else
                {
                    //错误处理,或者等一会,再次尝试加锁
                }

6.解锁

pthread_mutex_unlock(pthread_mutex_t *mutex);

下面我们用互斥锁写一个例子,用两个线程数数,每一个线程数10000,不加锁是数不到两万的。只有加锁之后才可以到两万,(虚拟机必须是双核的)

  1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 
  7 
  8 #define MAX 10000
  9 //数数需要创建一个全局变量
 10 int num;
 11 //创建一个全局变量的锁
 12 pthread_mutex_t mutex;
 13 
 14 void *fun1(void * arg)
 15 {
 16     int i = 0;
 17     for(;i < MAX;i++)
 18     {
 19         pthread_mutex_lock(&mutex);
 20         int tmp = num;
 21         tmp++;
 22         num = tmp;
 23 
 24         printf("first pthread = %lu,num = %d\n",pthread_self,num);
 25         pthread_mutex_unlock(&mutex);
 26 
 27         usleep(10);
 28     }
 29 
 30     return NULL;
 31 }
 32 
 33 void *fun2(void *arg)
 34 {
 35     int i = 0;
 36     for(;i < MAX;i++)
 37     {
 38         pthread_mutex_lock(&mutex);
 39         int tmp = num;
 40         tmp++;
 41         num = tmp;;
 42 
 43         printf("scend pthread = %lu,num = %d\n",pthread_self(),num);
 44         pthread_mutex_unlock(&mutex);
 45 
 46         usleep(10);
 47     }
 48 
 49     return NULL;
 50 }
 51 int main()
 52 {
 53     //定义两个线程ID
 54     pthread_t p1,p2;
 55 
 56     //初始化互斥锁
 57     pthread_mutex_init(&mutex,NULL);
 58     //创建两个线程
 59     pthread_create(&p1,NULL,fun1,NULL);
 60     pthread_create(&p2,NULL,fun2,NULL);
 61 
 62 
 63     //等待线程结束,获取线程的退出状态
 64     pthread_join(p1,NULL);
 65     pthread_join(p2,NULL);
 66 
 67     return 0;
 68 }

没加锁时,两个线程访问这个全局变量num是并行的,但是在在加锁之后就成串行的了,之后一个用完之后,另一个才能用。相当于满了很多,但是却实现了线程的同步。

你可能感兴趣的:(linux)