最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux多線(xiàn)程使用互斥量同步線(xiàn)程

 更新時(shí)間:2016年10月24日 11:52:43   作者:ljianhui  
本文主要介紹了Linux多線(xiàn)程使用互斥量同步線(xiàn)程,詳細(xì)介紹了互斥量的使用,有需要的可以了解一下。

本文將會(huì)給出互斥量的詳細(xì)解說(shuō),并用一個(gè)互斥量解決上一篇文章中,要使用兩個(gè)信號(hào)量才能解決的只有子線(xiàn)程結(jié)束了對(duì)輸入的處理和統(tǒng)計(jì)后,主線(xiàn)程才能繼續(xù)執(zhí)行的問(wèn)題。

一、什么是互斥量

互斥量是另一種用于多線(xiàn)程中的同步訪(fǎng)問(wèn)方法,它允許程序鎖住某個(gè)對(duì)象,使得每次只能有一個(gè)線(xiàn)程訪(fǎng)問(wèn)它。為了控制對(duì)關(guān)鍵代碼的訪(fǎng)問(wèn),必須在進(jìn)入這段代碼之前鎖住一個(gè)互斥量,然后在完成操作之后解鎖。

二、互斥量的函數(shù)的使用

它們的定義與使用信號(hào)量的函數(shù)非常相似,它們的定義如下:

#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); 

它們的意義就如它們的名字所示的那樣,成功時(shí)返回0,失敗時(shí)返回錯(cuò)誤代碼,它們并不設(shè)置errno。

pthread_mutex_init函數(shù)中的參數(shù)mutexattr指定互斥量的屬性,在這里我們并不關(guān)心互斥量的屬性,所以把它設(shè)置為NULL,使用默認(rèn)屬性即可。同樣的,pthread_mutex_lock和pthread_mutex_unlock都是原子操作,如果一個(gè)線(xiàn)程調(diào)用pthread_mutex_lock試圖鎖住互斥量,而該互斥量,又被其他線(xiàn)程鎖?。ㄕ加茫?,則該線(xiàn)程的pthread_mutex_lock調(diào)用就會(huì)阻塞,直到其他線(xiàn)程對(duì)該互斥量進(jìn)行解鎖,該線(xiàn)程才能獲得該互斥量,pthread_mutex_lock調(diào)用才會(huì)返回。

注意,使用互斥量的默認(rèn)屬性,如果程序試圖對(duì)一個(gè)已經(jīng)加鎖的互斥量調(diào)用pthread_mutex_lock,程序就會(huì)阻塞,而又因?yàn)閾碛谢コ饬康倪@個(gè)線(xiàn)程正是現(xiàn)在被阻塞的線(xiàn)程,所以這個(gè)互斥量就永遠(yuǎn)不會(huì)被解鎖,也就是說(shuō),程序就會(huì)進(jìn)入死鎖的狀態(tài)。在使用時(shí)要多加注意,確保在同一個(gè)線(xiàn)程中,對(duì)加鎖的互斥再次進(jìn)行加鎖前要對(duì)其進(jìn)行解鎖。

三、使用互斥量進(jìn)行線(xiàn)程同步

下面以一個(gè)簡(jiǎn)單的多線(xiàn)程程序來(lái)演示如何使用互斥量來(lái)進(jìn)行線(xiàn)程同步。在主線(xiàn)程中,我們創(chuàng)建子線(xiàn)程,并把數(shù)組msg作為參數(shù)傳遞給子線(xiàn)程,然后主線(xiàn)程調(diào)用函數(shù)pthread_mutex_lock對(duì)互斥量加鎖,等待輸入,輸入完成后,調(diào)用函數(shù)pthread_mutex_unlock對(duì)互斥量解鎖,從而使線(xiàn)程函數(shù)中的對(duì)互斥量加鎖的pthread_mutex_lock函數(shù)返回并執(zhí)行子線(xiàn)程中的代碼。線(xiàn)程函數(shù)在把字符串的小寫(xiě)字母變成大寫(xiě)并統(tǒng)計(jì)輸入的字符數(shù)量之后,它調(diào)用pthread_mutex_unlock對(duì)互斥量解鎖,使主線(xiàn)程能夠繼續(xù)獲得互斥量(即對(duì)其加鎖函數(shù)返回),再次執(zhí)行輸入功能直到主線(xiàn)程再次調(diào)用pthread_mutex_unlock對(duì)其解鎖,一直如此重復(fù),直到輸入end。

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

、#include <unistd.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
 
 
//聲明線(xiàn)程函數(shù)和互斥量 
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'}; 
  //初始化互斥量,使用默認(rèn)的互斥量屬性 
  res = pthread_mutex_init(&mutex, NULL); 
  if(res != 0) 
  { 
    perror("pthread_mutex_init failed\n"); 
    exit(EXIT_FAILURE); 
  } 
  //創(chuàng)建子線(xiàn)程,并把msg作為線(xiàn)程函數(shù)的參數(shù)傳遞給thread_func 
  res = pthread_create(&thread, NULL, thread_func, msg); 
  if(res != 0) 
  { 
    perror("pthread_create failed\n"); 
    exit(EXIT_FAILURE); 
  } 
  //輸入字符串,以串‘end'結(jié)束 
  printf("Input some test. Enter 'end' to finish\n"); 
  //把互斥量mutex加鎖,以確保同一時(shí)間只有該線(xiàn)程可以訪(fǎng)問(wèn)msg中的數(shù)據(jù) 
  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解鎖,讓其他的線(xiàn)程可以訪(fǎng)問(wèn)msg中的數(shù)據(jù) 
    pthread_mutex_unlock(&mutex); 
    sleep(1);//休眠1秒再繼續(xù)循環(huán),讓其他線(xiàn)程有執(zhí)行的機(jī)會(huì) 
    pthread_mutex_lock(&mutex); 
  } 
  pthread_mutex_unlock(&mutex); 
  printf("\nWaiting for thread finish...\n"); 
  //等待子線(xiàn)程結(jié)束 
  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加鎖,以確保同一時(shí)間只有該線(xiàn)程可以訪(fǎng)問(wèn)msg中的數(shù)據(jù) 
  pthread_mutex_lock(&mutex); 
  while(strcmp("end\n", msg) != 0) 
  { 
    //把小寫(xiě)字母變成大寫(xiě) 
    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解鎖,讓其他的線(xiàn)程可以訪(fǎng)問(wèn)msg中的數(shù)據(jù) 
    pthread_mutex_unlock(&mutex); 
    sleep(1);//休眠1秒再繼續(xù)循環(huán),讓其他線(xiàn)程有執(zhí)行的機(jī)會(huì) 
    pthread_mutex_lock(&mutex); 
  } 
  pthread_mutex_unlock(&mutex); 
  //退出線(xiàn)程 
  pthread_exit(NULL); 
} 

運(yùn)行結(jié)果如下:

程序分析:

這個(gè)程序的工作流程已經(jīng)說(shuō)得非常清楚了,這里先來(lái)說(shuō)說(shuō)在main函數(shù)和線(xiàn)程函數(shù)thread_func中while循環(huán)中的sleep(1)語(yǔ)句的作用??赡芎芏嗳藭?huì)認(rèn)為這個(gè)sleep(1)是為了讓子線(xiàn)程完成其處理和統(tǒng)計(jì)功能,所以要讓主線(xiàn)程休眠1秒鐘來(lái)等待子線(xiàn)程的處理統(tǒng)計(jì)工作的完成。的確在這里子線(xiàn)程進(jìn)行的工作十分簡(jiǎn)單,1秒鐘內(nèi)的確可以處理統(tǒng)計(jì)完畢。但是這里的sleep(1)并不是為了實(shí)現(xiàn)這個(gè)功能,這兩個(gè)循環(huán)中的sleep(1)是為了讓其他的線(xiàn)程有機(jī)會(huì)被執(zhí)行到,如果在一次的加鎖和解鎖之間沒(méi)有這條語(yǔ)句的話(huà),則當(dāng)前的線(xiàn)程將會(huì)一直在循環(huán)中獲得互斥量,因?yàn)槠渌木€(xiàn)程沒(méi)有執(zhí)行它的代碼的時(shí)間,所以就要用這樣的一條語(yǔ)句來(lái)給其他的線(xiàn)程一個(gè)運(yùn)行的機(jī)會(huì)。如果子線(xiàn)程的執(zhí)行時(shí)間超過(guò)1秒,這個(gè)程序還是會(huì)正常運(yùn)行。

以這個(gè)例子來(lái)說(shuō),在主線(xiàn)程中,當(dāng)輸入數(shù)據(jù)完畢并對(duì)互斥量解鎖之后,并不馬上循環(huán)對(duì)其加鎖,此時(shí)子線(xiàn)程就有了執(zhí)行的機(jī)會(huì),它會(huì)對(duì)互斥量進(jìn)行加鎖,同樣地,當(dāng)它處理統(tǒng)計(jì)完輸入的數(shù)據(jù)后,它在進(jìn)入下一次循環(huán)前,也休眠1秒,讓主線(xiàn)程有機(jī)會(huì)再次運(yùn)行。而主線(xiàn)程什么時(shí)候能夠執(zhí)行,取決于子線(xiàn)程何時(shí)對(duì)互斥量進(jìn)行解鎖。因?yàn)槿绻泳€(xiàn)程擁有(鎖?。┗コ饬浚瑒t主線(xiàn)程中函數(shù)pthread_mutex_lock就不會(huì)返回,使主線(xiàn)程處于阻塞狀態(tài)。

換句話(huà)來(lái)說(shuō),就是只有子線(xiàn)程結(jié)束了對(duì)輸入的處理和統(tǒng)計(jì)后,主線(xiàn)程才能繼續(xù)執(zhí)行,向msg中寫(xiě)入數(shù)據(jù)??吹竭@里,你應(yīng)該知道之前在使用信號(hào)量時(shí),我們多用一個(gè)信號(hào)量也是為了達(dá)到這個(gè)目的。所以當(dāng)我們輸入TEST時(shí),程序有兩個(gè)輸入,但還是能正常運(yùn)行,同樣解決了之前使用一個(gè)信號(hào)量時(shí)所帶來(lái)的問(wèn)題。

信號(hào)量和互斥量的作用都是保護(hù)代碼段的互斥設(shè)備,它們也非常相似。但在本例中,與使用信號(hào)量相比,實(shí)現(xiàn)同樣的功能,如果使用信號(hào)量的話(huà),則需要兩個(gè)信號(hào)量,而使用互斥量的話(huà),只需要一個(gè)??梢哉f(shuō)在本例中,使用互斥量更簡(jiǎn)單。但是我覺(jué)得使用互斥量更容易犯錯(cuò),我們可以看到在這個(gè)例子中,我們需要使用sleep語(yǔ)句來(lái)讓其他線(xiàn)程獲得執(zhí)行的機(jī)會(huì),但是在使用信號(hào)量的程序,它并不需要使用sleep,相對(duì)來(lái)說(shuō)比較直觀。我知道可能是我的實(shí)現(xiàn)方法不好,但是對(duì)于使用互斥量來(lái)說(shuō),我想了很久也想不到不使用sleep的方法。

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

相關(guān)文章

最新評(píng)論

建德市| 青浦区| 武陟县| 孟州市| 平南县| 许昌市| 平和县| 巢湖市| 开鲁县| 山丹县| 潮安县| 杨浦区| 昭苏县| 香格里拉县| 龙海市| 黑龙江省| 阿克| 海兴县| 永昌县| 芦山县| 鄂托克前旗| 山西省| 上思县| 白沙| 来宾市| 商河县| 康定县| 双城市| 昭平县| 尉犁县| 盘锦市| 通州区| 新泰市| 平南县| 扎囊县| 鄂托克前旗| 韶关市| 永川市| 通城县| 西青区| 密山市|