一、互斥量的屬性
就像線程有屬性一樣,線程的同步互斥量也有屬性,比較重要的是程序共享屬性和類型屬性。互斥量的屬性用pthread_mutexattr_t類型的資料
表示,當然在使用之前必須進行初始化,使用完成之後需要進行銷毀:
1)、互斥量初始化
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
2)、互斥量銷毀
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
二、互斥量的程序共享屬性
程序共享屬性有兩種值:
1)、PTHREAD_PROCESS_PRIVATE,這個是預設值,同一個程序中的多個線程通路同一個同步對象
2)、PTHREAD_PROCESS_SHARED, 這個屬性可以使互斥量在多個程序中進行同步,如果互斥量在多程序的共享記憶體區域,那麼具有這個屬性的
互斥量可以同步多程序
設定互斥量程序共享屬性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
程序共享屬性需要檢測系統是否支援,可以檢測宏_POSIX_THREAD_PROCESS_SHARED
三、互斥量的類型屬性
類型屬性
互斥量類型 沒有解鎖時再次加鎖 不占用是解鎖 已解鎖時解鎖
PTHREAD_MUTEX_NORMAL 死鎖 未定義 未定義
PTHREAD_MUTEX_ERRORCHEK 傳回錯誤 傳回錯誤 傳回錯誤
PTHREAD_MUTEX_RECURSIVE 允許 傳回錯誤 傳回錯誤
PTHREAD_MUTEX_DEFAULT 未定義 未定義 未定義
擷取/設定互斥量的類型屬性
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
四、讀寫鎖與條件變量的屬性
1、讀寫鎖也有屬性,它隻有一個程序共享屬性
讀寫鎖屬性初始化
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
設定讀寫鎖程序共享屬性
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
2、條件變量也有程序共享屬性
條件變量屬性初始化
int pthread_condattr_destroy(pthread_condattr_t *attr);
int pthread_condattr_init(pthread_condattr_t *attr);
設定條件變量屬性
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
五、手冊
PTHREAD_MUTEXATTR_DESTROY(3POSIX Programmer’s ManPTHREAD_MUTEXATTR_DESTROY(3P)
PROLOG
This manual page is part of the POSIX Programmer’s Manual. The Linux implementation of this interface may differ (con-
sult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on
Linux.
//這隻是POSIX的手冊,Linux對這個接口的實作可能不一樣,或者有的根本沒有實作這個接口
NAME
pthread_mutexattr_destroy, pthread_mutexattr_init - destroy and initialize the mutex attributes object
//初始化或者銷毀互斥量的屬性
SYNOPSIS
#include
//頭檔案
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
DESCRIPTION
The pthread_mutexattr_destroy() function shall destroy a mutex attributes object; the object becomes, in effect, unini-
tialized. An implementation may cause pthread_mutexattr_destroy() to set the object referenced by attr to an invalid
value. A destroyed attr attributes object can be reinitialized using pthread_mutexattr_init(); the results of otherwise
referencing the object after it has been destroyed are undefined.
//pthread_mutexattr_destroy()會銷毀一個互斥量屬性,這個屬性将變成一個沒有被初始化的值。或者有的實作可能導緻
//互斥量的屬性是一個無效的值。一個已經被銷戶的互斥量屬性可以重新被初始化,使用一個已經被銷毀的屬性會導緻未
//知的結果
The pthread_mutexattr_init() function shall initialize a mutex attributes object attr with the default value for all of
the attributes defined by the implementation.
//pthread_mutexattr_init()初始化一個互斥量的屬性
Results are undefined if pthread_mutexattr_init() is called specifying an already initialized attr attributes object.
//如果初始化一個已經被初始化過的屬性,那麼結果是未知的
After a mutex attributes object has been used to initialize one or more mutexes, any function affecting the attributes
object (including destruction) shall not affect any previously initialized mutexes.
//對于已經初始化的屬性,不會影響以前的互斥量
RETURN VALUE
Upon successful completion, pthread_mutexattr_destroy() and pthread_mutexattr_init() shall return zero; otherwise, an
error number shall be returned to indicate the error.
//成功傳回0,失敗傳回錯誤碼
ERRORS
The pthread_mutexattr_destroy() function may fail if:
//pthread_mutexattr_destroy() 在以下情況失敗
EINVAL The value specified by attr is invalid.
//屬性值是無效的
The pthread_mutexattr_init() function shall fail if:
// pthread_mutexattr_init()會在以下情況失敗
ENOMEM Insufficient memory exists to initialize the mutex attributes object.
//沒有記憶體去初始化屬性
These functions shall not return an error code of [EINTR].
//不會傳回EINTR
PTHREAD_MUTEXATTR_GETPSHAREPOSIX Programmer’s PTHREAD_MUTEXATTR_GETPSHARED(3P)
pthread_mutexattr_getpshared, pthread_mutexattr_setpshared - get and set the process-shared attribute
//擷取或者設定互斥量的程序共享屬性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t * restrict attr, int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
The pthread_mutexattr_getpshared() function shall obtain the value of the process-shared attribute from the attributes
object referenced by attr. The pthread_mutexattr_setpshared() function shall set the process-shared attribute in an ini-
tialized attributes object referenced by attr.
//pthread_mutexattr_getpshared()會擷取到互斥量的程序共享屬性,pthread_mutexattr_setpshared()可以設定互斥量的程序
//共享屬性
The process-shared attribute is set to PTHREAD_PROCESS_SHARED to permit a mutex to be operated upon by any thread that
has access to the memory where the mutex is allocated, even if the mutex is allocated in memory that is shared by multi-
ple processes. If the process-shared attribute is PTHREAD_PROCESS_PRIVATE, the mutex shall only be operated upon by
threads created within the same process as the thread that initialized the mutex; if threads of differing processes
attempt to operate on such a mutex, the behavior is undefined. The default value of the attribute shall be PTHREAD_PRO-
CESS_PRIVATE.
//程序共享屬性是PTHREAD_PROCESS_SHARED,這樣會允許互斥量在任何不同的線程之間同步資料,甚至這兩個線程不在同一個
//程序裡。 如果屬性是PTHREAD_PROCESS_PRIVATE,那麼互斥量僅僅允許在同一程序範圍内同步資料,如果不同程序之間同步資料
//那麼結果是未知的。預設的屬性是 PTHREAD_PROCESS_PRIVATE
Upon successful completion, pthread_mutexattr_setpshared() shall return zero; otherwise, an error number shall be
returned to indicate the error.
Upon successful completion, pthread_mutexattr_getpshared() shall return zero and store the value of the process-shared
attribute of attr into the object referenced by the pshared parameter. Otherwise, an error number shall be returned to
indicate the error.
//成功傳回0,而且互斥量的程序共享屬性被儲存起來,否則傳回錯誤碼
The pthread_mutexattr_getpshared() and pthread_mutexattr_setpshared() functions may fail if:
//在以下情況失敗
//屬性值是無效的
The pthread_mutexattr_setpshared() function may fail if:
//pthread_mutexattr_setpshared()會在以下情況失敗
EINVAL The new value specified for the attribute is outside the range of legal values for that attribute.
//設定的屬性值不在規定範圍之内
PTHREAD_MUTEXATTR_GETTYPE(3POSIX Programmer’s ManPTHREAD_MUTEXATTR_GETTYPE(3P)
pthread_mutexattr_gettype, pthread_mutexattr_settype - get and set the mutex type attribute
//擷取或者設定互斥量的類型
The pthread_mutexattr_gettype() and pthread_mutexattr_settype() functions, respectively, shall get and set the mutex
type attribute. This attribute is set in the type parameter to these functions. The default value of the type attribute
is PTHREAD_MUTEX_DEFAULT.
// pthread_mutexattr_gettype() and pthread_mutexattr_settype() 擷取或者設定互斥量的類型。類型會在參數中設定,預設的
//屬性是PTHREAD_MUTEX_DEFAULT.
The type of mutex is contained in the type attribute of the mutex attributes. Valid mutex types include:
//互斥量的類型包含在它的屬性中,有效的類型包括:
PTHREAD_MUTEX_NORMAL
This type of mutex does not detect deadlock. A thread attempting to relock this mutex without first unlocking it
shall deadlock. Attempting to unlock a mutex locked by a different thread results in undefined behavior.
Attempting to unlock an unlocked mutex results in undefined behavior.
//這個類型不會檢測死鎖,當一個線程試圖加鎖一個還沒被解鎖的互斥量,那麼就可能死鎖。試圖解鎖被其他線程
//鎖住的互斥量,結果是未知的。解鎖已經被解鎖的互斥量結果是未知的
PTHREAD_MUTEX_ERRORCHECK
This type of mutex provides error checking. A thread attempting to relock this mutex without first unlocking it
shall return with an error. A thread attempting to unlock a mutex which another thread has locked shall return
with an error. A thread attempting to unlock an unlocked mutex shall return with an error.
//這個類型會提供錯誤檢測。當一個線程試圖加鎖一個還沒被解鎖的互斥量,那麼就會傳回錯誤碼。試圖解鎖被其他線程
//鎖住的互斥量,傳回錯誤。解鎖已經被解鎖的互斥量,傳回錯誤
PTHREAD_MUTEX_RECURSIVE
A thread attempting to relock this mutex without first unlocking it shall succeed in locking the mutex. The
relocking deadlock which can occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of
mutex. Multiple locks of this mutex shall require the same number of unlocks to release the mutex before another
thread can acquire the mutex. A thread attempting to unlock a mutex which another thread has locked shall return
with an error. A thread attempting to unlock an unlocked mutex shall return with an error.
//重新鎖住一個未解鎖的互斥量會成功。在正常情況下會造成死鎖,但是這種類型的卻不會。多次鎖住互斥量應該有對應的
//多次解鎖操作。試圖解鎖被其他線程鎖住的互斥量,傳回錯誤。解鎖已經被解鎖的互斥量,傳回錯誤
PTHREAD_MUTEX_DEFAULT
Attempting to recursively lock a mutex of this type results in undefined behavior. Attempting to unlock a mutex
of this type which was not locked by the calling thread results in undefined behavior. Attempting to unlock a
mutex of this type which is not locked results in undefined behavior. An implementation may map this mutex to one
of the other mutex types.
//這種類型下,多次鎖住互斥量是未知的結果。試圖解鎖一個未加鎖的互斥量,結果是未知的。試圖去解鎖一個
//其他線程加鎖的互斥量,結果是未知的。有的實作會将這種類型映射到其他類型
Upon successful completion, the pthread_mutexattr_gettype() function shall return zero and store the value of the type
attribute of attr into the object referenced by the type parameter. Otherwise, an error shall be returned to indicate
the error.
//成功傳回0, pthread_mutexattr_gettype() 會儲存類型值,失敗傳回錯誤碼
If successful, the pthread_mutexattr_settype() function shall return zero; otherwise, an error number shall be returned
to indicate the error.
The pthread_mutexattr_settype() function shall fail if:
//pthread_mutexattr_settype() 會在以下情況失敗
EINVAL The value type is invalid.
//類型值無效
The pthread_mutexattr_gettype() and pthread_mutexattr_settype() functions may fail if:
//pthread_mutexattr_gettype() and pthread_mutexattr_settype() 在以下情況失敗
六、執行個體
互斥量屬性使用
1、程式架構

2、源代碼
點選(此處)折疊或打開
#include "apue.h"
int main()
{
char *shm = "myshm";
char *shm1 = "myshm1";
int shm_id, shm_id1;
char *buf;
pid_t pid;
pthread_mutex_t *mutex;
pthread_mutexattr_t mutexattr;
//打開共享記憶體
shm_id1 = shm_open(shm1, O_RDWR|O_CREAT, 0644);
//調整共享記憶體大小
ftruncate(shm_id1, 100);
//映射共享記憶體,MAP_SHARED屬性表明,對共享記憶體的任何修改都會影響其他程序
mutex =(pthread_mutex_t *)mmap(NULL, 100, PROT_READ|PROT_WRITE, MAP_SHARED, shm_id1, 0);
pthread_mutexattr_init(&mutexattr);
#ifdef _POSIX_THREAD_PROCESS_SHARED
pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED);
#endif
pthread_mutex_init(mutex, &mutexattr);
shm_id = shm_open(shm, O_RDWR|O_CREAT, 0644);
ftruncate(shm_id, 100);
buf =(char *)mmap(NULL, 100, PROT_READ|PROT_WRITE, MAP_SHARED, shm_id, 0);
pid = fork();
if(pid==0)
{
//休眠1s,讓父程序先運作
sleep(1);
printf("I'm child proccess\n");
pthread_mutex_lock(mutex);
//将共享記憶體記憶體修改為hello
memcpy(buf, "hello", 6);
printf("child buf is : %s\n", buf);
pthread_mutex_unlock(mutex);
}
else if(pid>0)
{
printf("I'm parent proccess\n");
//修改共享記憶體到内容,改為world
memcpy(buf, "world", 6);
sleep(3);
printf("parent buf is : %s\n", buf);
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(mutex);
//解除映射
munmap(buf, 100);
//消除共享記憶體
shm_unlink(shm);
munmap(mutex, 100);
shm_unlink(shm1);
}