第十二章 POSIX 執行緒(三)

2021-06-03 00:24:09 字數 3247 閱讀 8290

用互斥量進行同步

另一種用在多執行緒程式中的同步訪問方法是使用互斥量。它允許程式設計師鎖住某個物件,使得每次只有乙個執行緒訪問它。為了控制對關鍵**的訪問,必須在進入這段**之前鎖住乙個互斥量,然後在完成操作之後解鎖它。

#include

int pthread_mutex_init(pthread_mutex_t *mutex,  const pthread_mutexattr_t 

*mutexattr);

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

成功時返回 0,失敗返回錯誤**,但這些函式並不設定 errno,你必須對函式的返回**進行檢查。

與訊號量相類似,這些函式的引數都是乙個先前宣告過的以乙個指向前面宣告的物件的指標為引數,在互斥方法是乙個pthread_mutex_t。額外的屬性引數pthread_mutexattr_t允許我們為互斥提供屬性,這可以控制其行為。屬性型別預設為"fast"。這有乙個小的缺點,如果我們的程式試著在乙個已經上鎖的互斥量上呼叫pthread_mutex_lock,程式就會阻塞。因為擁有鎖的執行緒現在被阻塞了,互斥量就不會被解鎖,從而程式就會進入死鎖狀態。可以修改互斥量的屬性,從而他或者可以檢測這種情況並返回乙個錯誤,或者是迴圈操作並且在同乙個執行緒上允許多個鎖。

實驗--執行緒互斥量

#include #include #include #include #include #include void *thread_function(void *arg);

pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */

#define work_size 1024

char work_area[work_size];

int time_to_exit = 0;

int main()

res = pthread_create(&a_thread, null, thread_function, null);

if (res != 0)

pthread_mutex_lock(&work_mutex);

printf("input some text. enter 'end' to finish\n");

while(!time_to_exit)

else }}

pthread_mutex_unlock(&work_mutex);

printf("\nwaiting for thread to finish...\n");

res = pthread_join(a_thread, &thread_result);

if (res != 0)

printf("thread joined\n");

pthread_mutex_destroy(&work_mutex);

exit(exit_success);

}void *thread_function(void *arg)

}time_to_exit = 1;

work_area[0] = '\0';

pthread_mutex_unlock(&work_mutex);

pthread_exit(0);

}

執行

$ ./thread4

input some text. enter 『end』 to finish

whit

you input 4 characters

the crow road

you input 13 characters

endwaiting for thread to finish...

thread joined

實驗解析

在程式的開始,我們宣告了乙個互斥量、工作區和乙個變數 time_to_exit。如下所示:

pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */

#define work_size 1024

char work_area[work_size];

int time_to_exit = 0;

然後初始化互斥量:

res = pthread_mutex_init(&work_mutex, null);

if (res != 0)

接下來啟動新執行緒:

pthread_mutex_lock(&work_mutex);

while(strncmp("end", work_area, 3) != 0)

}time_to_exit = 1;

work_area[0] = '\0';

pthread_mutex_unlock(&work_mutex);

pthread_exit(0);

新執行緒首先試圖對互斥量加鎖。如果它已經被鎖住,這個呼叫將被阻塞直到它被釋放為止。一旦獲得訪問權,我們就檢查是否有申請退出程式的請求。如果就設定 time_to_exit 變數,再把工作區的第乙個字元設定為 \0,然後退出。

如果不想退出,就統計字元個數,然後把 work_area 中的第乙個字元設定為 null。我們用將第乙個字元設定為 null 的方法通知讀取輸入的執行緒,我們已經完成了字元統計。然後解鎖互斥量並等待主線程繼續執行。我們將周期性地嘗試給互斥量加鎖,如果加鎖成功,就檢查是否主線程又有字元送來要處理。如果還沒有,就解鎖互斥量繼續等待;如果有,就統計字元個數並再次進入迴圈。

下面是主線程的程式:

pthread_mutex_lock(&work_mutex);

printf(「input some text. enter 『end』 to finish/n」);

while(!time_to_exit)

else }}

pthread_mutex_unlock(&work_mutex);

這段**和上面新執行緒中的很相似。我們首先給工作區加鎖,讀入文字到它裡面,然後解鎖以允許其它執行緒訪問它並統計字元數目。我們周期性地對互斥量再加鎖,檢查字元數目是否已統計完(work_area[0]被設定為null)。如果還需要等待,就釋放互斥量。如前所述,這種通過輪詢來獲得結果的方法通常並不是最好的程式設計方式。在實際的程式設計中,我們應該盡量用訊號量來避免出現這種情況。

第十二章 POSIX 執行緒(一)

在乙個程式中的多個執行線路就叫做執行緒 thread 更準確的定義是 執行緒是乙個程序內部的乙個控制序列。執行緒有一套完整的與其相關的函式庫呼叫,它們中的絕大多數函式名都是以 pthread 開頭,為了使用這些函式庫呼叫,我們必須定義巨集 peentrant,在程式中包含頭文 件 pthread.h...

第十二章 執行緒控制

1.執行緒屬性 int pthread attr init pthread attr t attr int pthread attr destroy pthread attr t attr int pthread attr getdetachstate const pthread attr t re...

第十二章 檔案

文字檔案 文字檔案是一種由若干字元構成的檔案,可以用文字編輯器進行閱讀或編輯。以txt py html等為字尾的檔案都是文字檔案。2.二進位制檔案 二進位制檔案一般是指不能用文字編輯器閱讀或編輯的檔案。以 mp4 png等為字尾的檔案都是二進位制檔案,如果想要開啟或修改這些檔案,必須通過特定軟體進行...