浅议互斥锁

线程最大的特点就是资源的共享性,然而资源共享中的同步问题是多线程编程的难点。互斥锁通过锁机制来实现线程间的同步。使用互斥锁前必须进行初始化操作。初始化有两种方式:一种是静态赋值法,将将宏结构常量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,这就是线程间抢占资源造成的结果。下次再聊


你可能感兴趣的:(thread,多线程,编程,c,linux)