1.初始化與銷毀互斥量
linux使用pthread_mutex_t 資料型別表示互斥量,並使用pthread_mutex_init函式對互斥量進行初始化。
#include
int pthread_mutex_init(pthread_mutex_t * restrict mutex,const pthread_mutexattr * restrict attr);
第乙個引數是互斥量的指標,互斥量在該函式內被初始化。第二個引數是互斥量的屬性,一般置為null。
linux還提供了另一種初始化互斥量的方法,使用者可以將互斥量設定為pthread_mutex_initializer,這種方法有個侷限性,那就是如果互斥量是使用動態分配記憶體的方法得到的,那麼就不能使用如下方法初始化訊號量。
pthread_mutex_t * mutex;
mutex=(pthead_mutex_t * )malloc(sizeof(pthread_mutex_t));
mutex=pthread_mutex_initializer;
以上的初始化是錯誤的。原因在於linux將pthread_mutex_t 型別定義為結構體,而pthread_mute_initializer常量相當於已經設定好的結構體變數中每乙個成員變數的值。顯而易見,乙個已經定義的結構體物件可以使用這種方法,而乙個利用malloc得來的結構體物件不能夠使用這種方法。
如果要使用pthread_mutex_initializer,可以這樣用。
pthread_mutex_t mutex=pthread_mutex_initializer;
當乙個互斥量不再使用時,使用如下函式用如下函式將其銷毀。
#include
int pthread_mutex_destroy(pthread_mutex_t * mutex);
2.得到與釋放互斥量
#include
int pthread_mutex_lock(pthread_mutex_t * mutex);
int pthread_mutex_trylock(pthread_mutex_t * mutex);
int pthread_mutex_unlock(pthread_mutex_t * mutex);
第乙個函式在所要求的互斥量的鎖已被其他執行緒所取得的情況下,會阻塞呼叫執行緒。第二個函式不會阻塞呼叫執行緒,會立即返回ebusy。表示鎖處於繁忙狀態。
用第二個函式實現乙個非阻塞的加鎖函式版本,用於忙等待乙個互斥量的鎖。
while(pthread_mutex_trylock(&mutex)==ebusy);
3.例項
該程式維護乙個任務佇列,其本質是乙個鍊錶。兩個執行緒掃瞄鍊錶,將屬於自己的任務從任務列表中摘下。
兩個執行緒分別對鍊錶程序讀操作。為了防止可中斷的讀寫之間造成的資料不一致的錯誤,使用互斥量。
//mutex_list.c
#include
#include
#include
#include
#define max_item 3 /* 每次最多取三個任務 */
typedef struct job * job;
/* 鍊錶節點結構 */
struct job;
pthread_mutex_t q_lock = pthread_mutex_initializer; /* 全域性變數鎖 */
int insert(job *head, int val, pthread_t tid)
}
q = (struct job *)malloc(sizeof(struct job));
if(q == null)
q->next = null;
q->val = val;
q->tid = tid;
p->next = q;
if(p == null)
p->next = q;
return 0;
} void get_job(job head, job task, int *count)
else
} }
int free_job(job head)
return 0;
} void print(job head)
void * tfn7(void * arg)
print((job) arg);
if(free_job(task) == -1)
exit(1);
return (void *)0;
} int main(void)
if((err = pthread_create(&tid2, null, tfn7, item)) != 0)
printf("===the 1st put===/n");
pthread_mutex_lock(&q_lock);
for(i = 0; i < 2; i++)
if(insert(&item, 10, tid1) == -1)
exit(1);
pthread_mutex_unlock(&q_lock);
sleep(5);
/* 休眠,保證執行緒可以取走任務節點,在這裡不能使用pthread_join函式
*因為佇列中只有兩個節點屬於執行緒2,未取走3個節點執行緒是不會退出的
*所以pthread_join函式會導致死鎖
*/ printf("===the 2nd put===/n");
pthread_mutex_lock(&q_lock);
if(insert(&item, 9, tid2) == -1)
exit(1);
pthread_mutex_unlock(&q_lock);
err = pthread_join(tid1, null);
if(err != 0)
err = pthread_join(tid2, null);
if(err != 0)
printf("main thread done/n");
if(item->next == null)
printf("no job in the queue/n");
free(item);
return 0;
}
執行緒同步 互斥量
下面以乙個簡單的多執行緒程式來演示如何使用互斥量來進行執行緒同步。在主線程中,我們建立子執行緒,並把陣列msg作為引數傳遞給子執行緒,然後主線程呼叫函式pthread mutex lock對互斥量加鎖,等待輸入,輸入完成後,呼叫函式pthread mutex unlock對互斥量解鎖,從而使執行緒函...
執行緒同步 互斥量
互斥量的使用 執行緒同步之互斥量 include include include include include include include using namespace std 全域性變數,兩個執行緒都可以修改,因此修改的時候需要加鎖 int g value 0 互斥量 pthread mu...
執行緒同步(互斥量)
原理 建立與銷毀 include int pthread mutex init pthread mutex t restrict mutex,const pthread mutexattr t restrict attr int pthread mutex destroy pthread mutex...