說遞回互斥量前,說下互斥量都有哪些,apue第三版上說有下面4種:
-
PTHREAD_MUTEX_NORMAL:標準型別,不做任何特殊的錯誤檢查或者死鎖檢測,
在同一個執行緒里去鎖一個還沒有解鎖的互斥量時,發生死鎖,
-
PTHREAD_MUTEX_RECURSIVE:遞回型別,
此互斥量型別允許同一執行緒在互斥量解鎖前對該互斥量進行多次加鎖,遞回互斥量維護鎖的計數,在解鎖次數和加鎖次數不相同的情況下,不會釋放鎖,別的執行緒就無法加鎖此互斥量,
-
PTHREAD_MUTEX_ERRORCHECK:提供錯誤檢測,如果在同一個執行緒里去鎖一個還沒有解鎖的互斥量,會報告錯誤,但在centos7(3.10.0-957.el7.x86_64),gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)上測驗過,發現:在同一個執行緒里去鎖一個還沒有解鎖的互斥量,沒有報告錯誤,
-
PTHREAD_MUTEX_DEFAULT
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)環境里pthread.h里,互斥量型別的定義如下:
/* Mutex types. */
enum
{
PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_ADAPTIVE_NP
#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
,
PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
/* For compatibility. */
, PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};
下面的例子驗證遞回互斥量.
例子很簡單,在main函式里創建2個執行緒,在執行緒1的函式fn1,加鎖互斥量2次,但是只解鎖一次,執行緒fn2就無法給互斥量加鎖,導致一直阻塞在①處,
為了能夠讓執行緒fn1能夠先給互斥量加鎖,在fn2里呼叫了sleep函式,讓fn2先睡眠1秒,所以fn1就能夠先給互斥量加鎖了,
去掉②處的注釋,fn2就能鎖定mutex了,程式就不會出現死鎖狀態了,
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
pthread_mutex_t mt;
int i = 0;
void* fn1(void* agr)
{
int err;
pthread_mutex_lock(&mt);
if((err = pthread_mutex_lock(&mt)) < 0)
{
printf("%s\n", strerror(err));
exit(1);
}
++i;
printf("%d\n", i);
//pthread_mutex_unlock(&mt);//-------②
pthread_mutex_unlock(&mt);
}
void* fn2(void* arg)
{
sleep(1);//目的是讓執行緒fn1先執行,
pthread_mutex_lock(&mt);//-----------①
++i;
printf("second %d\n", i);
pthread_mutex_unlock(&mt);
}
int main()
{
pthread_t tid1, tid2;
pthread_mutexattr_t mat;
pthread_mutexattr_init(&mat);
//設定鎖的型別為遞回鎖
pthread_mutexattr_settype(&mat, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mt, &mat);
pthread_create(&tid1, NULL, fn1, NULL);
pthread_create(&tid2, NULL, fn2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mt);
}
c/c++ 學習互助QQ群:877684253
本人微信:xiaoshitou5854

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/40819.html
標籤:C
下一篇:VC6.0設定注釋快捷鍵
