linux线程同步之互斥锁——linux的关键区域
在windows中,為了讓多個線程達到同步的目的,在對于全局變量等大家都要用的資源的使用上,通常得保證同時只能由一個線程在用,一個線程沒有宣布對它的釋放之前,不能夠給其他線程使用這個變量。在windows里,我們可以用時EnterCriticalSection()和LeaveCriticalSection()函數.那么在linux里,有什么類似的機制呢?
?
這里介紹互斥鎖。
1.申請一個互斥鎖
pthread_mutex_t mutex; //申請一個互斥鎖
你可以聲明多個互斥量。
在聲明該變量后,你需要調用pthread_mutex_init()來創建該變量。pthread_mutex_init的格式如下:
int?pthread_mutex_init(pthread_mutex_t?*mutex,?const?pthread_mutexattr_t *mutexattr);
第一個參數,mutext,也就是你之前聲明的那個互斥量,第二個參數為該互斥量的屬性。屬性定義如下:
互斥量分為下面三種:
l???????? 快速型(PTHREAD_MUTEX_FAST_NP
)。這種類型也是默認的類型。該線程的行為正如上面所說的。l???????? 遞歸型(PTHREAD_MUTEX_RECURSIVE_NP
)。如果遇到我們上面所提到的死鎖情況,同一線程循環給互斥量上鎖,那么系統將會知道該上鎖行為來自同一線程,那么就會同意線程給該互斥量上鎖。l???????? 錯誤檢測型(PTHREAD_MUTEX_ERRORCHECK_NP
)。如果該互斥量已經被上鎖,那么后續的上鎖將會失敗而不會阻塞,pthread_mutex_lock()操作將會返回EDEADLK。?
可以通過函數
注意以下語句可以做到將一個互斥鎖快速初始化為快速型。
pthread_mutex_t? mutex = PTHREAD_MUTEX_INITIALIZER;
?
2.銷毀一個互斥鎖
pthread_mutex_destroy()用于注銷一個互斥鎖,API定義如下:
?int pthread_mutex_destroy(pthread_mutex_t *mutex)
銷毀一個互斥鎖即意味著釋放它所占用的資源,且要求鎖當前處于開放狀態。由于在Linux中,互斥鎖并不占用任何資源,因此LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態以外(鎖定狀態則返回EBUSY)沒有其他動作。
?
3.上鎖(相當于windows下的EnterCriticalSection)
在創建該互斥量之后,你便可以使用它了。要得到互斥量,你需要調用下面的函數:
int pthread_mutex_lock(pthread_mutex_t *mutex);
該函數用來給互斥量上鎖。互斥量一旦被上鎖后,其他線程如果想給該互斥量上鎖,那么就會阻塞在這個操作上。如果在此之前該互斥量已經被其他線程上鎖,那么該操作將會一直阻塞在這個地方,直到獲得該鎖為止。
在得到互斥量后,你就可以進入關鍵代碼區了。
?
4.解鎖(相當于windows下的LeaveCriticalSection)
在操作完成后,你必須調用下面的函數來給互斥量解鎖,也就是前面所說的釋放。這樣其他等待該鎖的線程才有機會獲得該鎖,否則其他線程將會永遠阻塞。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
?
5.pthread_mutex_trylock
如果我們不想一直阻塞在這個地方,那么可以調用下面函數:
int pthread_mutex_trylock(pthread_mutex_t *mutex)
如果此時互斥量沒有被上鎖,那么pthread_mutex_trylock()將會返回0,并會對該互斥量上鎖。如果互斥量已經被上鎖,那么會立刻返回EBUSY。
?
使用示例代碼如下:
?
Code#include?<malloc.h>
#include?<pthread.h>
struct?job?{
????/*?Link?field?for?linked?list.?*/
????struct?job*?next;
????/*?Other?fields?describing?work?to?be?done?*/
};
/*?A?linked?list?of?pending?jobs.?*/
struct?job*?job_queue;
/*?A?mutex?protecting?job_queue.?*/
pthread_mutex_t?job_queue_mutex?=?PTHREAD_MUTEX_INITIALIZER;
/*?Process?queued?jobs?until?the?queue?is?empty.?*/
void*?thread_function?(void*?arg)
{
????while?(1)?{
????????struct?job*?next_job;
????????/*?Lock?the?mutex?on?the?job?queue.?*/
????????pthread_mutex_lock?(&job_queue_mutex);
????????/*?Now?it’s?safe?to?check?if?the?queue?is?empty.?*/
????????if?(job_queue?==?NULL)
????????????next_job?=?NULL;
????????else?{
????????????/*?Get?the?next?available?job.?*/
????????????next_job?=?job_queue;
????????????/*?Remove?this?job?from?the?list.?*/
????????????job_queue?=?job_queue->next;
????????}
????????/*?Unlock?the?mutex?on?the?job?queue?because?we’re?done?with?the
????????queue?for?now.?*/
????????pthread_mutex_unlock?(&job_queue_mutex);
????????/*?Was?the?queue?empty??If?so,?end?the?thread.?*/
????????if?(next_job?==?NULL)
????????????break;
????????/*?Carry?out?the?work.?*/
????????process_job?(next_job);
????????/*?Clean?up.?*/
????????free?(next_job);
????}
????return?NULL;
}
?
?
轉載于:https://www.cnblogs.com/aicro/archive/2009/06/17/1505322.html
總結
以上是生活随笔為你收集整理的linux线程同步之互斥锁——linux的关键区域的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典学英语
- 下一篇: 将枚举值转换为DropDownList等