以前学操作系统的进程和线程管理时,经常听到互斥加锁解锁之类的概念,但是几乎很少在编程中用到,今天看《gnu/linux编程》的线程这章时,对c程序中如何给变量加锁解锁有了一个大致的了解,现记录如下:
互斥其实是保证线程在关键区正常执行的变量,同一时刻只能由某一进程访问,要建立一个关键区,首先得创建一个互斥变量,然后用特殊的符号为其常量初始化。互斥变量声明方法如下:
pthread_mutex_t test_mutex=PTHREAD_MUTEX_INITIALIZER;
互斥变量初始化有三种类型,具体的类型请google搜索。下面创建关键区:
pthread_mutex_t test_mutex=PTHREAD_MUTEXT_INITIALIZER;
。。。
/*进入关键区*/
assert(pthread_mutex_lock(&test_mutex)==0);
attr++; //要锁定的变量,同一时刻只能某一线程访问
assert(pthread_mutext_unlock(&test_mutex)==0);
/*退出关键区*/
关键区是同一时刻只允许某一线程执行的代码段,关键区的存在是为了保护共享资源,避免多重访问的发生。
pthread_mutex_trylock()方法与pthread_mutex_lock()的区别是trylock如果不能成功加锁可以干其他的事情,而不是阻塞于加锁关键区,而lock则是如不能加锁关键区则阻塞于此,直到可以加锁为止。
互斥变量用完最后得销毁,通过pthread_mutex_destroy()来销毁即可。
一个完整实例如下:
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#define MAX 1000
#define MAX_THREAD 10
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
long counter = 0L;
void *mythread(void *args)
{
int i, ret;
for(i=0; i<MAX; i++)
{
ret = pthread_mutex_lock(&mymutex);
assert(ret == 0);
counter++;
ret = pthread_mutex_unlock(&mymutex);
assert(ret == 0);
}
}
int main()
{
int ret, i;
pthread_t threadId[MAX_THREAD];
for(i=0; i< MAX_THREAD; i++)
{
ret = pthread_create(&threadId[i],NULL,mythread,NULL);
if(ret != 0)
printf("Error creating thread %d\n",(int)threadId[i]);
}
for(i=0; i<MAX_THREAD; i++)
{
ret = pthread_join(threadId[i],NULL);
if(ret != 0)
printf("Error joining thread %d\n",(int)threadId[i]);
}
printf("The protected varible value is %ld\n",counter);
ret = pthread_mutex_destroy(&mymutex);
if(ret != 0)
printf("Couldn't destroy the mutex\n");
return 0;
}
参考: http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html