轉載自:http://www.linuxidc.com/Linux/2011-03/33227.htm
/*1.線程訪問機制
1.1引言:
任務間的關係有兩種:1,間接關係;2,直接關係。
例如1. 任務A對莫個緩衝區進行寫操作。任務B從這個緩衝區進行讀操作。那麼A和B的關係就是直接的關係,那麼實現這種直接關係的機制就是同步
2. 任務A要使用打印機,任務b也要使用打印機,那麼只有在任務A使用結束的情況下才能使用打印機,所以A和B的關係是間接的關係。那麼要實現這種間接的關係的機制是互斥.
在linux中實現線程間的互斥和同步的主要的機制是:信號量和互斥鎖
1.2互斥鎖
mutex 是一種簡單的加鎖的方法來控制對共享資源的存取。這個互斥鎖只有兩種狀態,也就是上鎖和解鎖。
可以把互斥鎖看作某種意義上的全局變量。在同一時刻只能有一個線程掌握某個互斥上的鎖,擁有上鎖狀態的線程能夠對共享資源進行操作。若其他線程希望上鎖一個已經上鎖了的互斥鎖,則該線程就會掛起,直到上鎖的線程釋放掉互斥鎖爲止。可以說,這把互斥鎖使得共享資源按序在各個線程中操作。
互斥鎖的操作主要包括以下幾個步驟。
互斥鎖初始化:pthread_mutex_init
互斥鎖上鎖:pthread_mutex_lock
互斥鎖判斷上鎖:pthread_mutex_trylock
互斥鎖接鎖:pthread_mutex_unlock
消除互斥鎖:pthread_mutex_destroy
其中,互斥鎖可以分爲快速互斥鎖、遞歸互斥鎖和檢錯互斥鎖。這三種鎖的區別主要在於其他未佔有互斥鎖的線程在希望得到互斥鎖時的是否需要阻塞等待。快速鎖是指調用線程會阻塞直至擁有互斥鎖的線程解鎖爲止。遞歸互斥鎖能夠成功地返回並且增加調用線程在互斥上加鎖的次數,而檢錯互斥鎖則爲快速互斥鎖的非阻塞版本,它會立即返回並返回一個錯誤信息。
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)//互斥鎖初始化函數
mutexattr = PTHREAD_MUTEX_INITIALIZER:創建快速互斥鎖,快速鎖是指調用線程會阻塞直至擁有互斥鎖的線程解鎖爲止
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:創建遞歸函數傳入值 Mutexattr 互斥鎖,遞歸互斥鎖能夠成功地返回並且增加調用線程在互斥上加鎖的次數
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:創建檢錯互斥鎖,而檢錯互斥鎖則爲快速互斥鎖的非阻塞版本.
int pthread_mutex_lock(pthread_mutex_t *mutex,) //互斥鎖上鎖
int pthread_mutex_trylock(pthread_mutex_t *mutex,) //互斥鎖判斷上鎖
int pthread_mutex_unlock(pthread_mutex_t *mutex,) //互斥鎖接鎖
int pthread_mutex_destroy(pthread_mutex_t *mutex,) //消除互斥鎖
*/
//實例:
/*mutex.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int lock_var;
time_t end_time;
void pthread1(void *arg);
void pthread2(void *arg);
int main(int argc, char *argv[])
{
pthread_t id1,id2;
pthread_t mon_th_id;
int ret;
end_time = time(NULL)+10;
/*互斥鎖初始化*/
pthread_mutex_init(&mutex,NULL);
/*創建兩個線程*/
ret=pthread_create(&id1,NULL,(void *)pthread1, NULL);
if(ret!=0)
perror("pthread cread1");
ret=pthread_create(&id2,NULL,(void *)pthread2, NULL);
if(ret!=0)
perror("pthread cread2");
pthread_join(id1,NULL);
pthread_join(id2,NULL);
exit(0);
}
void pthread1(void *arg)
{
int i;
while(time(NULL) < end_time)
{
/*互斥鎖上鎖*/
if(pthread_mutex_lock(&mutex)!=0)
{
perror("pthread_mutex_lock");
}
else
printf("pthread1:pthread1 lock the variable\n");
for(i=0;i<2;i++){
sleep(1);
lock_var++;
}
/*互斥鎖接鎖*/
if(pthread_mutex_unlock(&mutex)!=0){
perror("pthread_mutex_unlock");
}
else
printf("pthread1:pthread1 unlock the variable\n");
sleep(1);
}
}
void pthread2(void *arg)
{
int nolock=0;
int ret;
while(time(NULL) < end_time)
{
/*測試互斥鎖*/
ret=pthread_mutex_trylock(&mutex);
if(ret==EBUSY)
printf("pthread2:the variable is locked by pthread1\n");
else
{
if(ret!=0)
{
perror("pthread_mutex_trylock");
exit(1);
}
else
printf("pthread2:pthread2 got lock.The variable is%d\n",lock_var);
/*互斥鎖接鎖*/
if(pthread_mutex_unlock(&mutex)!=0)
{
perror("pthread_mutex_unlock");
}
else
printf("pthread2:pthread2 unlock the variable\n");
}
sleep(3);
}
}