以下是您提供的文本內容的排版整理版本。我已根據內容主題將其分為幾個主要部分(互斥鎖、信號量、死鎖、IPC進程間通信、管道操作),并使用清晰的結構組織信息:
- 代碼片段用代碼塊格式(指定語言為C)突出顯示。
- 函數定義和步驟使用有序列表整理。
- 關鍵概念用加粗或小標題強調。
- 整體結構基于邏輯順序優化,確保易讀性,但未修改原始內容含義。
互斥鎖機制
互斥機制確保多線程中對臨界資源的排他性訪問(公共資源)。框架包括定義、初始化、加鎖、解鎖和銷毀步驟。
定義互斥鎖:
pthread_mutex_t mutex; // 互斥鎖類型變量
初始化鎖:
- 函數:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
- 功能:初始化已定義的互斥鎖。
- 參數:
mutex
:要初始化的互斥鎖指針。attr
:初始化屬性值,通常為NULL
(表示默認鎖)。
- 返回值:成功返回
0
,失敗返回非零值。
- 函數:
加鎖:
- 函數:
int pthread_mutex_lock(pthread_mutex_t *mutex);
- 功能:對指定代碼加鎖,加鎖后代碼為原子操作(其他線程無法訪問)。
- 參數:
mutex
為互斥鎖指針。 - 返回值:成功返回
0
,失敗返回非零值。 - 注意:如果鎖已被占用,則阻塞當前線程。
- 函數:
解鎖:
- 函數:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 功能:解鎖指定互斥鎖。
- 參數:
mutex
為互斥鎖指針。 - 返回值:成功返回
0
,失敗返回非零值。 - 注意:加鎖和解鎖通常成對出現。
- 函數:
銷毀鎖:
- 函數:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
- 功能:銷毀互斥鎖。
- 參數:
mutex
為互斥鎖指針。 - 返回值:成功返回
0
,失敗返回非零值。
- 函數:
非阻塞鎖(trylock):
- 函數:
int pthread_mutex_trylock(pthread_mutex_t *mutex);
- 功能:類似加鎖,但不阻塞。
- 參數:
mutex
為互斥鎖指針。 - 返回值:成功返回
0
,失敗返回非零值(如EAGAIN
)。
- 注意:互斥鎖控制排他訪問,但不保證次序。
- 函數:
信號量機制(Linux線程同步)
信號量用于線程或進程間同步,分類為:
- 無名信號量:線程間通信。
- 有名信號量:進程間通信。
框架包括定義、初始化、PV操作和銷毀。
定義信號量:
sem_t sem; // 信號量類型變量
初始化信號量:
- 函數:
int sem_init(sem_t *sem, int pshared, unsigned int value);
- 功能:初始化已定義的信號量。
- 參數:
sem
:信號量指針。pshared
:0
表示線程間使用,非0
表示進程間使用。value
:初始值(例如,二值信號量中,0
表示阻塞,1
表示通過)。
- 返回值:成功返回
0
,失敗返回非零值。
- 函數:
PV操作:
- P操作(申請資源):
sem_wait(sem_t *sem);
(功能:減少信號量值,如果值為0則阻塞)。 - V操作(釋放資源):
sem_post(sem_t *sem);
(功能:增加信號量值,喚醒等待線程)。 - 注意:PV操作確保同步。
- P操作(申請資源):
銷毀信號量:
- 函數:
int sem_destroy(sem_t *sem);
- 功能:銷毀信號量。
- 參數:
sem
為信號量指針。 - 返回值:成功返回
0
,失敗返回非零值。
- 函數:
死鎖原因與必要條件
死鎖產生原因:
- 系統資源不足。
- 進程運行推進順序不合適。
- 資源分配不當。
死鎖必要條件:
- 互斥條件:一個資源每次只能被一個進程使用。
- 請求與保持條件:進程因請求資源阻塞時,對已獲得資源保持不放。
- 不剝奪條件:進程已獲得資源在未使用完前不能被強行剝奪。
- 循環等待條件:若干進程形成頭尾相接的循環等待資源關系。
注意:如果資源充足,死鎖可能性低;否則易因爭奪資源發生。
IPC進程間通信分類
IPC(Inter-Process Communicate)分為三大類:
古老通信方式:
- 無名管道。
- 有名管道。
- 信號(唯一異步通信方式)。
IPC對象通信(System V):
- 消息隊列(較少使用)。
- 共享內存(最高效方式)。
- 信號量集。
Socket通信:用于網絡通信。
特例:線程信號使用sem_init
(POSIX標準)。
管道操作(有名管道)
管道操作框架:打開、讀寫、關閉、卸載。
打開有名管道:
- 函數:
int open(const char *pathname, int flags);
- 注意:
- 管道為半雙工模式,打開方式決定讀寫端。
- 示例:
int fd_read = open("./fifo", O_RDONLY); // 固定為讀端 int fd_write = open("./fifo", O_WRONLY); // 固定為寫端
- 禁止使用
O_RDWR
(讀寫模式)或O_CREAT
(創建選項),管道創建需用mkfifo
函數。
- 注意:
- 函數:
管道讀寫:
- 讀操作:
read(fd_read, buff, sizeof(buff));
- 寫操作:
write(fd_write, buff, sizeof(buff));
- 讀操作:
關閉管道:
- 函數:
close(fd);
- 函數:
卸載管道:
- 函數:
int unlink(const char *pathname);
- 功能:移除管道文件。
- 函數: