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

      和多进程相比,多线程的最大特点就是资源的共享。然而共享却涉及到一个同步的问题,这是多线程编程的难点。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;

//线程1
void 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);
    }
}

//线程2
void 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");
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值