亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

Linux多線程使用互斥量同步線程

2024-09-05 23:02:42
字體:
來源:轉載
供稿:網友

本文將會給出互斥量的詳細解說,并用一個互斥量解決上一篇文章中,要使用兩個信號量才能解決的只有子線程結束了對輸入的處理和統計后,主線程才能繼續執行的問題。

一、什么是互斥量

互斥量是另一種用于多線程中的同步訪問方法,它允許程序鎖住某個對象,使得每次只能有一個線程訪問它。為了控制對關鍵代碼的訪問,必須在進入這段代碼之前鎖住一個互斥量,然后在完成操作之后解鎖。

二、互斥量的函數的使用

它們的定義與使用信號量的函數非常相似,它們的定義如下:

#include <pthread.h> 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_init函數中的參數mutexattr指定互斥量的屬性,在這里我們并不關心互斥量的屬性,所以把它設置為NULL,使用默認屬性即可。同樣的,pthread_mutex_lock和pthread_mutex_unlock都是原子操作,如果一個線程調用pthread_mutex_lock試圖鎖住互斥量,而該互斥量,又被其他線程鎖?。ㄕ加茫?,則該線程的pthread_mutex_lock調用就會阻塞,直到其他線程對該互斥量進行解鎖,該線程才能獲得該互斥量,pthread_mutex_lock調用才會返回。

注意,使用互斥量的默認屬性,如果程序試圖對一個已經加鎖的互斥量調用pthread_mutex_lock,程序就會阻塞,而又因為擁有互斥量的這個線程正是現在被阻塞的線程,所以這個互斥量就永遠不會被解鎖,也就是說,程序就會進入死鎖的狀態。在使用時要多加注意,確保在同一個線程中,對加鎖的互斥再次進行加鎖前要對其進行解鎖。

三、使用互斥量進行線程同步

下面以一個簡單的多線程程序來演示如何使用互斥量來進行線程同步。在主線程中,我們創建子線程,并把數組msg作為參數傳遞給子線程,然后主線程調用函數pthread_mutex_lock對互斥量加鎖,等待輸入,輸入完成后,調用函數pthread_mutex_unlock對互斥量解鎖,從而使線程函數中的對互斥量加鎖的pthread_mutex_lock函數返回并執行子線程中的代碼。線程函數在把字符串的小寫字母變成大寫并統計輸入的字符數量之后,它調用pthread_mutex_unlock對互斥量解鎖,使主線程能夠繼續獲得互斥量(即對其加鎖函數返回),再次執行輸入功能直到主線程再次調用pthread_mutex_unlock對其解鎖,一直如此重復,直到輸入end。

源文件為lockthread.c,源代碼如下:

、#include <unistd.h> #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <string.h>   //聲明線程函數和互斥量 void* thread_func(void *msg); pthread_mutex_t mutex;   #define MSG_SIZE 512   int main() {   int res = -1;   pthread_t thread;   void *thread_result = NULL;   char msg[MSG_SIZE] = {'/0'};   //初始化互斥量,使用默認的互斥量屬性   res = pthread_mutex_init(&mutex, NULL);   if(res != 0)   {     perror("pthread_mutex_init failed/n");     exit(EXIT_FAILURE);   }   //創建子線程,并把msg作為線程函數的參數傳遞給thread_func   res = pthread_create(&thread, NULL, thread_func, msg);   if(res != 0)   {     perror("pthread_create failed/n");     exit(EXIT_FAILURE);   }   //輸入字符串,以串‘end'結束   printf("Input some test. Enter 'end' to finish/n");   //把互斥量mutex加鎖,以確保同一時間只有該線程可以訪問msg中的數據   pthread_mutex_lock(&mutex);   while(strcmp("end/n", msg) != 0)   {     if(strncmp("TEST", msg, 4) == 0)     {       strcpy(msg, "copy_data/n");     }     else     {       fgets(msg, MSG_SIZE, stdin);     }     //把互斥量mutex解鎖,讓其他的線程可以訪問msg中的數據     pthread_mutex_unlock(&mutex);     sleep(1);//休眠1秒再繼續循環,讓其他線程有執行的機會     pthread_mutex_lock(&mutex);   }   pthread_mutex_unlock(&mutex);   printf("/nWaiting for thread finish.../n");   //等待子線程結束   res = pthread_join(thread, &thread_result);   if(res != 0)   {     perror("pthread_join failed/n");     exit(EXIT_FAILURE);   }   printf("Thread joined/n");   //清理互斥量   pthread_mutex_destroy(&mutex);   exit(EXIT_SUCCESS); } void* thread_func(void *msg) {   int i = 0;   char *ptr = msg;   sleep(1);   //把互斥量mutex加鎖,以確保同一時間只有該線程可以訪問msg中的數據   pthread_mutex_lock(&mutex);   while(strcmp("end/n", msg) != 0)   {     //把小寫字母變成大寫     for(i = 0; ptr[i] != '/0'; ++i)     {       if(ptr[i] >= 'a' && ptr[i] <='z')       {         ptr[i] -= 'a' - 'A';       }     }     printf("You input %d characters/n", i-1);     printf("To uppercase: %s/n", ptr);     //把互斥量mutex解鎖,讓其他的線程可以訪問msg中的數據     pthread_mutex_unlock(&mutex);     sleep(1);//休眠1秒再繼續循環,讓其他線程有執行的機會     pthread_mutex_lock(&mutex);   }   pthread_mutex_unlock(&mutex);   //退出線程   pthread_exit(NULL); } 

運行結果如下:

linux多線程互斥,linux,多線程同步,線程同步互斥

程序分析:

這個程序的工作流程已經說得非常清楚了,這里先來說說在main函數和線程函數thread_func中while循環中的sleep(1)語句的作用。可能很多人會認為這個sleep(1)是為了讓子線程完成其處理和統計功能,所以要讓主線程休眠1秒鐘來等待子線程的處理統計工作的完成。的確在這里子線程進行的工作十分簡單,1秒鐘內的確可以處理統計完畢。但是這里的sleep(1)并不是為了實現這個功能,這兩個循環中的sleep(1)是為了讓其他的線程有機會被執行到,如果在一次的加鎖和解鎖之間沒有這條語句的話,則當前的線程將會一直在循環中獲得互斥量,因為其他的線程沒有執行它的代碼的時間,所以就要用這樣的一條語句來給其他的線程一個運行的機會。如果子線程的執行時間超過1秒,這個程序還是會正常運行。

以這個例子來說,在主線程中,當輸入數據完畢并對互斥量解鎖之后,并不馬上循環對其加鎖,此時子線程就有了執行的機會,它會對互斥量進行加鎖,同樣地,當它處理統計完輸入的數據后,它在進入下一次循環前,也休眠1秒,讓主線程有機會再次運行。而主線程什么時候能夠執行,取決于子線程何時對互斥量進行解鎖。因為如果子線程擁有(鎖住)互斥量,則主線程中函數pthread_mutex_lock就不會返回,使主線程處于阻塞狀態。

換句話來說,就是只有子線程結束了對輸入的處理和統計后,主線程才能繼續執行,向msg中寫入數據??吹竭@里,你應該知道之前在使用信號量時,我們多用一個信號量也是為了達到這個目的。所以當我們輸入TEST時,程序有兩個輸入,但還是能正常運行,同樣解決了之前使用一個信號量時所帶來的問題。

信號量和互斥量的作用都是保護代碼段的互斥設備,它們也非常相似。但在本例中,與使用信號量相比,實現同樣的功能,如果使用信號量的話,則需要兩個信號量,而使用互斥量的話,只需要一個??梢哉f在本例中,使用互斥量更簡單。但是我覺得使用互斥量更容易犯錯,我們可以看到在這個例子中,我們需要使用sleep語句來讓其他線程獲得執行的機會,但是在使用信號量的程序,它并不需要使用sleep,相對來說比較直觀。我知道可能是我的實現方法不好,但是對于使用互斥量來說,我想了很久也想不到不使用sleep的方法。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕国产亚洲| 欧美国产日韩xxxxx| 国产成人精品国内自产拍免费看| 精品亚洲一区二区| 成人动漫网站在线观看| 亚洲欧洲在线视频| 日韩欧美精品免费在线| 综合网中文字幕| 亚洲欧美中文在线视频| 日韩日本欧美亚洲| 热99精品里视频精品| 欧美精品免费播放| 久久精品国亚洲| 欧美成aaa人片在线观看蜜臀| 911国产网站尤物在线观看| 色www亚洲国产张柏芝| 亚洲精品电影久久久| 久久久久久综合网天天| 欧美亚洲视频一区二区| 亚洲精品一区二区久| 亚洲国产精品热久久| 国产精品久久久久久久电影| 91成人福利在线| 国产va免费精品高清在线观看| 日韩欧美中文免费| 亚洲xxx视频| 久久久国产精品视频| 中文字幕亚洲一区二区三区| 欧美精品久久久久久久久| 欧美激情一区二区三区在线视频观看| 成人精品福利视频| 欧美日韩精品在线观看| 欧美电影免费观看网站| 中文字幕国产精品久久| 怡红院精品视频| 精品无人区太爽高潮在线播放| 午夜精品久久久久久久白皮肤| 成人免费视频a| 欧美激情一区二区三级高清视频| 日本成人激情视频| 成人av番号网| 日韩h在线观看| 日韩欧美在线免费观看| 麻豆国产精品va在线观看不卡| 国产欧美日韩丝袜精品一区| www.xxxx欧美| 国产精品欧美一区二区三区奶水| 国产欧美中文字幕| 91九色国产在线| 欧美高清在线观看| 欧美精品在线观看| 国产精品国产三级国产专播精品人| 欧美日韩国产一中文字不卡| 国产精品国产三级国产专播精品人| 亚洲va久久久噜噜噜久久天堂| 成人激情av在线| 欧美视频中文字幕在线| 亚洲成人网av| 97视频在线观看免费高清完整版在线观看| 欧美成人午夜激情在线| 色婷婷综合成人av| 91麻豆国产语对白在线观看| 97涩涩爰在线观看亚洲| 国产成人鲁鲁免费视频a| 国产精品视频免费在线| 色婷婷av一区二区三区久久| 亚洲精品天天看| 欧日韩在线观看| 97在线视频免费观看| 国产欧美一区二区三区四区| 欧美在线亚洲在线| www.欧美精品| 91精品中国老女人| 91精品国产综合久久久久久久久| 成人高h视频在线| 欧美大尺度激情区在线播放| 久久久久久久久久亚洲| 亚洲91精品在线观看| 国产一区二区三区中文| 欧亚精品在线观看| 日韩av手机在线看| 国产精品极品美女在线观看免费| 亚洲精品大尺度| 久久精彩免费视频| 成人国产在线激情| 久久久精品欧美| 国产精品久久久久久中文字| 一个人www欧美| 国产精品久久久久久久午夜| 亚洲天堂网站在线观看视频| 久久精品成人一区二区三区| 国产精品第一区| 日韩精品中文字幕在线| 国产成人精彩在线视频九色| 在线丨暗呦小u女国产精品| 91中文字幕一区| 久久精品成人欧美大片古装| 欧美日韩国产va另类| 久久久久999| 久久精品小视频| 久久久久999| 激情成人在线视频| 久久亚洲春色中文字幕| 亚洲电影第1页| 国产极品jizzhd欧美| 色噜噜狠狠狠综合曰曰曰88av| 欧美激情一区二区三区久久久| 尤物精品国产第一福利三区| 久久999免费视频| 欧美久久精品一级黑人c片| 欧美俄罗斯乱妇| 亚洲激情小视频| 一本一本久久a久久精品牛牛影视| 日本成人在线视频网址| 欧美成人免费视频| 亚洲精品国产免费| 亚洲精品免费在线视频| 亚洲精品动漫100p| 91精品成人久久| 国产精品一区二区久久| 日韩成人在线电影网| 98午夜经典影视| 久久亚洲私人国产精品va| 日韩国产中文字幕| 国产偷国产偷亚洲清高网站| 久久久精品网站| 91精品国产乱码久久久久久蜜臀| 韩日欧美一区二区| 亚洲日韩欧美视频一区| 精品福利一区二区| 亚洲美女中文字幕| 精品国产一区二区三区在线观看| 国产做受69高潮| 亚洲欧洲一区二区三区久久| 欧美日韩国产精品| 日韩女优人人人人射在线视频| 久久精品成人一区二区三区| 成人网在线视频| 国产精品爽黄69| 欧美视频13p| 国产欧美日韩亚洲精品| 69av在线视频| 欧美巨乳在线观看| 亚洲国产精品免费| 亚洲午夜av电影| 欧美激情视频一区| 欧美精品电影免费在线观看| 久久久精品视频在线观看| 一二美女精品欧洲| 国产va免费精品高清在线观看| 国产精品丝袜一区二区三区| 91精品久久久久久久久久久久久| 欧美成人手机在线| 成人妇女免费播放久久久| 成人性生交大片免费观看嘿嘿视频| 久久精品中文字幕| 国产成人在线精品| 国产成人在线视频| 久久久精品国产| 国产精品96久久久久久又黄又硬| 亚洲黄色www| 国产欧美久久一区二区| 国产精品久久电影观看| 中文字幕亚洲天堂|