當多個執行緒對共享資料同時操作時,為了保證共享資料的一致性,需要同步執行緒的讀寫操作。
1.1函式
1建立和銷毀互斥量
#include
/*動態建立和銷毀*/
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
返回值:若成功返回
0,否則返回錯誤編號
/*靜態初始化,不需要銷毀*/
pthread_mutex_t mutex = pthread_mutex_initializer;
2加鎖和解鎖互斥量
#include
/*加鎖
,如果互斥量已上鎖,呼叫執行緒將阻塞直到互斥量被解鎖。*/
int pthread_mutex_lock(pthread_mutex_t *mutex);
/*解鎖,不能解鎖由其他執行緒鎖住的互斥量*/
int pthread_mutex_unlock(pthread_mutex_t *mutex);
/*嘗試加鎖,如果互斥量已上鎖,呼叫執行緒返回失敗返回
ebusy
而不會阻塞*/
int pthread_mutex_trylock(pthread_mutex_t *mutex);
返回值:若成功返回
0,否則返回錯誤編號
1.2應用
/* errors.h*/
#ifndef __errors_h
#define __errors_h
#include #include #include #include #include #ifdef debug
#define dprintf(arg) printf arg
#else
#define dprintf(arg)
#endif
#define err_abort(code,text) dowhile(0)
#define errno_abort(text) do while(0)
#endif
#include "errors.h"
#include #include typedef struct alarm_tag
alarm_t;
pthread_mutex_t alarm_mutex = pthread_mutex_initializer;/*互斥量*/
alarm_t *alarm_list = null; /*全域性變數,此處為需要同步的共享資源*/
void *alarm_thread(void *arg)
else
else
#ifdef debug
printf("[waiting: %d(%d)\"%s\"]\n", alarm->time, sleep_time, alarm->message);
#endif
}/*解鎖*/
pthread_mutex_unlock(&alarm_mutex);
if (sleep_time > 0)
else
if (alarm != null)
}}int main(int argc, char *argv)
while (1)
if (sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2)
else
last = &next->link;
next = next->link;
}if (next == null)
#if debug
printf("[list: ");
for (next = alarm_list; next != null; next = next->link)
printf("%d(%d)[\"%s\"]", next->time, next->time - time(null), next->message);
printf("]\n");
#endif
/*解鎖*/
pthread_mutex_unlock(&alarm_mutex);}}
}
2.1函式 1
條件變數初始化
#include
int pthread_cond_init(pthread_cond_t * cond, pthread_condattr_t * attr);
int pthread_cond_destroy(pthread_cond_t *cond);
返回值:成功返回
0,失敗返回錯誤碼
pthread_cond_t cond = pthread_cond_initializer;/*
靜態初始化*/
2等待條件變數
標頭檔案#include
函式int pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);
引數cond
: 條件變數
mutex
:互斥量,用來同步共享資料。
返回值成功返回
0,失敗返回錯誤碼。等待條件變數總是返回鎖住的互斥量。
說明在乙個條件變數上等待會導致一下原子操作:
釋放相關互斥量,等待其他執行緒發給該條件變數訊號或廣播該條件變數。當等待條件變數時,互斥量必須始終為釋放的,這樣其他執行緒才有機會鎖住互斥量,修改條件變數;當執行緒從條件變數等待中醒來時,它重新繼續鎖住互斥量。
標頭檔案#include
函式int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex,
struct timespec *timeout);
引數cond
:條件變數
mutex
:互斥量
timeout
:等待的時間值,用秒數
tv_sec
或分秒數
tv_nsec
來表示。
struct timespec;
timeout
這個時間值是絕對數而不是相對數,例如等待
3分鐘,則需要把當前時間再加上
3分鐘再轉換到
timespec
結構。返回值
成功返回
0,失敗返回錯誤碼
3喚醒等待條件變數的執行緒
#include
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
返回值:成功返回
0,失敗返回錯誤碼
2.2應用
#include "errors.h"
#include #include typedef struct alarm_tag
alarm_t;
pthread_mutex_t alarm_mutex = pthread_mutex_initializer;
pthread_cond_t alarm_cond = pthread_cond_initializer;
alarm_t *alarm_list = null;
time_t current_alarm = 0;
void alarm_insert(alarm_t *alarm)
last = &next->link;
next = next->link;
}if (next == null)
#if debug
printf("[list: ");
for (next = alarm_list; next != null; next = next->link)
printf("%d(%d)[\"%s\"]", next->time, next->time - time(null), next->message);
printf("]\n");
#endif
if (current_alarm ==0 || alarm->time < current_alarm)
}}void *alarm_thread(void *arg)
/*摘取alarm鍊錶的第乙個元素*/
alarm = alarm_list;
alarm_list = alarm->link;
now = time(null);
expired = 0;
if (alarm->time > now)
if (status != 0)
}if (!expired)
}else
if (expired)
}}int main(int argc, char *argv)
while (1)
if (sscanf(line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2)
else
}}
第18章 多執行緒程式設計 3
18.5 threading模組 threading模組支援守護執行緒,它們是這樣工作的 守護執行緒一般是乙個等待客戶請求伺服器,如果客戶提出請求,它就在那等著。如果你設定乙個執行緒為守護執行緒,就表示你在說這個執行緒是不重要的,在程序退出的時候,不用等待這個執行緒退出。如果你想要等待子執行緒完成再...
Linux程式設計筆記(第12章 POSIX執行緒)
執行緒定義 執行緒是乙個程序內部的乙個控制序列。所有的程序都至少有乙個執行執行緒。當在乙個程序中建立乙個新執行緒時,新的執行執行緒將擁有自己的棧 因此也有自己的區域性變數 但與它的建立者共享全域性變數 檔案描述符 訊號處理函式和當前目錄狀態。執行緒介面 1 建立執行緒 include int pth...
POSIX多執行緒 非同步程式設計舉例
整半年沒有更新,發幾篇以前的讀書筆記。content 0.序 1.基本的同步版本 2.多程序版本 3.多執行緒版本 4.小結 0.序 本節通過乙個簡單的鬧鐘例項演示非同步程式設計方法。該程式迴圈接受使用者輸入資訊,直到出錯或者輸入完畢。使用者輸入的每行資訊有兩部分 鬧鐘等待的時間 秒 和鬧鐘時間到達...