线程同步1 ------ 互斥锁

来源:互联网 发布:中国电信网络在线测速 编辑:程序博客网 时间:2024/05/23 11:30

      和多进程相比,多线程的最大特点就是资源的共享。然而共享却涉及到一个同步的问题,这是多线程编程的难点。Linux系统提供了多种方式处理线程间的同步问题,主要有互斥锁、条件变量和异步信号。本文先讲互斥锁。


      互斥锁通过锁机制来实现线程间的同步。在同一个时刻,只允许一个线程执行一个关键部分的代码。

      使用互斥锁前必须对其进行初始化。有以下2种方式:

  1. 将宏结构常量PTHREAD_MUTEX_INITIALIZER赋给互斥锁。pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER。
  2. 另外是通过pthread_mutex_init函数初始化互斥锁。

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

      

      mutexattr表示互斥锁的属性,如果为NULL使用默认属性。


      初始化后,就可以给互斥锁加锁了。加锁的2个函数是:pthread_mutex_lock()和pthread_mutex_trylock()。它们的原型如下:

int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);

      用lock加锁时,如果mutex已经被锁住,当前尝试加锁的线程就会阻塞,直到互斥锁被其他线程释放。当加锁函数返回时,则说明互斥锁已经被当前线程成功加锁。trylock函数则不同,如果mutex已经被加锁,它会立即返回,错误码为EBUSY,而不会阻塞。

      

      pthread_mutex_unlock用来解锁,其原型为:

int pthread_mutex_unlock(pthread_mutex_t *mutex);


      解锁要满足两个条件:一是互斥锁必须处于加锁的状态;二是解锁的线程也必须是当初加锁的线程。解锁后如果有其他线程在等待互斥锁,则等待队列中的第一个线程将获得互斥锁。


      互斥锁使用完毕后,必须进行清除。清除互斥锁使用函数pthread_mutex_destroy,该函数原型为:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

      清除锁时要求锁处于开放的状态,清除成功返回0;否则函数返回EBUSY。


      以下例子演示通过互斥锁对全局变量在2个线程之间进行同步:

#include <stdio.h>#include <pthread.h>//声明锁和全局变量pthread_mutex_t number_mutex;int globalnumber;//线程1void thread1(){//对全局变量加值5次    int i=5;    while(i-->0){        pthread_mutex_lock(&number_mutex);//加锁        globalnumber++;        printf("Thread 1 added,globalnumber= %d\n",globalnumber);        pthread_mutex_unlock(&number_mutex);//解锁        sleep(1);    }}//线程2void thread2(){//对全局变量加值3次    int i=3;    while(i-->0){        pthread_mutex_lock(&number_mutex);//加锁        globalnumber++;        printf("Thread 2 added,globalnumber= %d\n",globalnumber);        pthread_mutex_unlock(&number_mutex);//解锁        sleep(2);    }}main(){    pthread_t thid1,thid2;    printf("This is Main Thread.\n");//互斥锁的初始化pthread_mutex_init(&number_mutex,NULL);    pthread_create(&thid1,NULL,thread1,NULL);    pthread_create(&thid2,NULL,thread2,NULL);    int status1,status2;    pthread_join(thid1,(void*)&status1);    pthread_join(thid2,(void*)&status2);//互斥锁的清除pthread_mutex_destroy(&number_mutex);//等待上述2个子线程运行结束,最后再讲2个子线程操作完毕的全局变量打印到屏幕    printf("globalnumber is: %d\n",globalnumber);    printf("Main Thread exit\n");}

运行结果: