线程最大的特点就是资源的共享性,然而资源共享中的同步问题是多线程编程的难点。互斥锁通过锁机制来实现线程间的同步。使用互斥锁前必须进行初始化操作。初始化有两种方式:一种是静态赋值法,将将宏结构常量PTHREAD_MUTEX_INITIALIZER赋给互斥锁,操作语句如下:
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
另一种方式是通过pthread_mutex_init函数初始化互斥锁,该函数的原型如下:
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t * mutexattr);
函数中的参数mutexattr表示互斥锁的属性,如果为NULL则使用默认属性。
初始化以后,就可以给互斥锁加锁了,加锁有两个函数:pthread_mutex_lock()和pthread_mutex_trylock();
用pthread_mutex_lock()加锁时,如果mutex已经被锁住,当前尝试加锁的线程就会阻塞,直到互斥锁被释放。当
pthread_mutex_lock函数返回时,说明互斥锁已经被当前线程成功加锁。pthread_mutex_trylock函数则不同,如果mutex已经加锁,它将立即返回,返回的错误码为EBUSY,而不是阻塞等待。
注:加锁时,不论哪种类型的锁,都不可能被两个不同的线程同时得到,其中一个必须等待解锁。在同一进程中的线程,如果加锁后没有解锁,则其他线程将无法再获得该锁。
函数pthread_mutex_unlock(pthread_mutex_t *mutex);
用pthread_mutex_unlock函数解锁时,要满足两个条件:一个是互斥锁处于加锁状态,二是调用本函数的线程必须是给互斥锁加锁的线程。解锁后如果有其他线程在等待互斥锁,等待队列中的第一个线程将获得互斥锁。
当一个互斥锁使用完毕后,必须进行清除。清除互斥锁使用函数pthread_mutex_destory,该函数原型如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
清除一个互斥锁意味着释放它所占用的资源,清除锁是要求当前处于开放状态,若锁处于锁定状态,函数返回EBUSY,该函数成功时返回哦0。由于在Linux中,互斥锁并不占用内存,因此pthread_mutex_destory()除了解除互斥锁的状态以外没有其他操作。
下面是我写的一个小例子。
#include<stdio.h>
#include<pthread.h> //引入线程头文件
int wu=0; //全局变量
pthread_mutex_t mut; //定义互斥锁变量
void thread(void) //线程1对全局变量做3333次自增操作
{
int i;
for(i=0;i<3333;i++)
{
pthread_mutex_lock(&mut); //加锁
wu++;
pthread_mutex_unlock(&mut); //解锁
printf("This is a pthread\n");
}
}
void thread2(void) //
{
int i;
for(i=0;i<2222;i++)//线程2对全局变量做2222次自增操作
{
pthread_mutex_lock(&mut); //加锁
wu++;
pthread_mutex_unlock(&mut); //解锁
printf("This is a pthread2\n");
}
}
int main()
{
pthread_t id=0,id2=0;
int i,ret,ret2;
pthread_mutex_init(&mut,NULL); //互斥锁的初始化
ret=pthread_create(&id,NULL,(void * )thread,NULL); //创建线程1
ret2=pthread_create(&id2,NULL,(void * )thread2,NULL); //创建线程2
if(ret!=0)
{
printf("Create pthread error!\n");
exit(1);
}
if(ret2!=0)
{
printf("Create pthread2 error!\n");
exit(1);
}
for(i=0;i<3;i++)
{
printf("This is the main process\n");
}
pthread_join(id,NULL); //等待线程1结束
pthread_join(id2,NULL); //等待线程2结束
printf("wu=%d\n",wu);
return (0);
}
[root@wuzhq thread]# ls
simple1.c th_ex th_pool thread_example.c thread_pool.c
[root@wuzhq thread]# gcc -o simple1 simple1.c -lpthread(这块的-lpthread不能缺少)
运行,得出wu=5555,始终为5555。试着把互斥锁去掉,会发现,结果每次都不一样,多数情况下都小于5555,这就是线程间抢占资源造成的结果。下次再聊