以下為使用 POSIX 線程(pthread)的死結範例 deadlock.c
/**
* A pthread program illustrating deadlock.
*
* Usage:
* gcc deadlock.c -lpthread
* ./a.out
*
* Figure 7.4
*
* @author Gagne, Galvin, Silberschatz
* Operating System Concepts - Ninth Edition
* Copyright John Wiley & Sons - 2013.
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t first_mutex;
pthread_mutex_t second_mutex;
void *do_work_one(void *param);
void *do_work_two(void *param);
int main(int argc, char *argv[])
{
pthread_t tid1, tid2; /* the thread identifiers */
pthread_attr_t attr; /* set of attributes for the thread */
/* get the default attributes */
pthread_attr_init(&attr);
/* create the mutex locks */
pthread_mutex_init(&first_mutex,NULL);
pthread_mutex_init(&second_mutex,NULL);
/* create the threads */
pthread_create(&tid1,&attr,do_work_one,NULL);
pthread_create(&tid2,&attr,do_work_two,NULL);
/* now wait for the thread to exit */
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("Parent DONE\n");
/* destroy the mutex before exiting */
pthread_mutex_destroy(&first_mutex);
pthread_mutex_destroy(&second_mutex);
}
/**
* The first thread worker
*/
void *do_work_one(void *param)
{
pthread_mutex_lock(&first_mutex);
printf("Worker 1 has acquired first mutex\n");
pthread_mutex_lock(&second_mutex);
printf("Worker 1 has acquired second mutex\n");
/**
* Do some work
*/
printf("Worker 1 is whistling .....\n");
pthread_mutex_unlock(&second_mutex);
pthread_mutex_unlock(&first_mutex);
printf("worker 1 done\n");
pthread_exit(0);
}
/**
* The second thread worker
*/
void *do_work_two(void *param)
{
pthread_mutex_lock(&second_mutex);
printf("Worker 2 has acquired second mutex\n");
pthread_mutex_lock(&first_mutex);
printf("Worker 2 has acquired first mutex\n");
/**
* Do some work
*
*/
printf("Worker 2 is whistling .....\n");
pthread_mutex_unlock(&first_mutex);
pthread_mutex_unlock(&second_mutex);
pthread_exit(0);
}
這個程式碼是一個使用 POSIX 線程(pthread)的 C 語言程式,用來演示死鎖(deadlock)的情況。讓我們請AI詳細解析這個程式:
程式結構:
main 函數:
do_work_one 函數:
do_work_two 函數:
死鎖情況:
這個程式演示了一個典型的死鎖場景:
編譯和運行:
gcc deadlock.c -lpthread
./a.out
潛在問題:
教學目的:
結果:
這個輸出表明:
程式開始執行。
Worker 2(do_work_two 函數)首先獲得了 second_mutex。
Worker 1(do_work_one 函數)接著獲得了 first_mutex。
程式在這裡停止了,沒有進一步的輸出。
這個情況正好演示了一個典型的死鎖:
兩個線程都在等待對方釋放自己需要的資源,但由於都不願意釋放自己持有的資源,導致程式陷入了死鎖狀態。
這個結果清楚地展示了程式中設計的死鎖情況:
這個死鎖情況的關鍵在於資源(互斥鎖)的請求順序:
這種交叉的資源請求順序是造成死鎖的常見原因。
解決這種死鎖的方法包括:
這個輸出很好地展示了為什麼在設計多線程程式時,正確處理資源分配和互斥是如此重要。它也說明了為什麼在實際應用中,我們需要謹慎設計並仔細測試涉及多個鎖的代碼。