欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Linux下的C編程入門(mén)之“線(xiàn)程”控制與“線(xiàn)程”通信編程

1.Linux“線(xiàn)程”

筆者曾經(jīng)在《基于嵌入式操作系統VxWorks的多任務(wù)并發(fā)程序設計》(《軟件報》2006年第5~12期)中詳細敘述了進(jìn)程和線(xiàn)程的區別,并曾經(jīng)說(shuō)明Linux是一種“多進(jìn)程單線(xiàn)程”的操作系統。Linux本身只有進(jìn)程的概念,而其所謂的“線(xiàn)程”本質(zhì)上在內核里仍然是進(jìn)程。大家知道,進(jìn)程是資源分配的單位,同一進(jìn)程中的多個(gè)線(xiàn)程共享該進(jìn)程的資源(如作為共享內存的全局變量)。Linux中所謂的“線(xiàn)程”只是在被創(chuàng )建的時(shí)候“克隆”(clone)了父進(jìn)程的資源,因此,clone出來(lái)的進(jìn)程表現為“線(xiàn)程”,這一點(diǎn)一定要弄清楚。 Linux內核只提供了輕量進(jìn)程的支持,未實(shí)現線(xiàn)程模型,但Linux盡最大努力優(yōu)化了進(jìn)程的調度開(kāi)銷(xiāo),這在一定程度上彌補無(wú)線(xiàn)程的缺陷。Linux用一個(gè)核心進(jìn)程(輕量進(jìn)程)對應一個(gè)線(xiàn)程,將線(xiàn)程調度等同于進(jìn)程調度,交給核心完成。

 

目前Linux中最流行的線(xiàn)程機制為L(cháng)inuxThreads,所采用的就是線(xiàn)程-進(jìn)程“一對一”模型,調度交給核心,而在用戶(hù)級實(shí)現一個(gè)包括信號處理在內的線(xiàn)程管理機制。LinuxThreads由Xavier Leroy (Xavier.Leroy@inria.fr)負責開(kāi)發(fā)完成,并已綁定在GLIBC中發(fā)行,它實(shí)現了一種BiCapitalized面向Linux的Posix 1003.1c “pthread”標準接口。Linuxthread可以支持Intel、Alpha、MIPS等平臺上的多處理器系統。
按照POSIX 1003.1c 標準編寫(xiě)的程序與Linuxthread 庫相鏈接即可支持Linux平臺上的多線(xiàn)程,在程序中需包含頭文件pthread. h,在編譯鏈接時(shí)使用命令:
gcc -D -REENTRANT -lpthread xxx. c
其中-REENTRANT宏使得相關(guān)庫函數(如stdio.h、errno.h中函數) 是可重入的、線(xiàn)程安全的(thread-safe),-lpthread則意味著(zhù)鏈接庫目錄下的libpthread.a或libpthread.so文件。使用Linuxthread庫需要2.0以上版本的Linux內核及相應版本的C庫(libc 5.2.18、libc 5.4.12、libc 6)。

2.“線(xiàn)程”控制

線(xiàn)程創(chuàng )建
進(jìn)程被創(chuàng )建時(shí),系統會(huì )為其創(chuàng )建一個(gè)主線(xiàn)程,而要在進(jìn)程中創(chuàng )建新的線(xiàn)程,則可以調用pthread_create:
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
  (start_routine)(void*), void *arg);
start_routine為新線(xiàn)程的入口函數,arg為傳遞給start_routine的參數。
每個(gè)線(xiàn)程都有自己的線(xiàn)程ID,以便在進(jìn)程內區分。線(xiàn)程ID在pthread_create調用時(shí)回返給創(chuàng )建線(xiàn)程的調用者;一個(gè)線(xiàn)程也可以在創(chuàng )建后使用pthread_self()調用獲取自己的線(xiàn)程ID:
pthread_self (void) ;
線(xiàn)程退出
線(xiàn)程的退出方式有三:
(1)執行完成后隱式退出;
(2)由線(xiàn)程本身顯示調用pthread_exit 函數退出;
pthread_exit (void * retval) ;
(3)被其他線(xiàn)程用pthread_cance函數終止:
pthread_cance (pthread_t thread) ;
在某線(xiàn)程中調用此函數,可以終止由參數thread 指定的線(xiàn)程。
如果一個(gè)線(xiàn)程要等待另一個(gè)線(xiàn)程的終止,可以使用pthread_join函數,該函數的作用是調用pthread_join的線(xiàn)程將被掛起直到線(xiàn)程ID為參數thread的線(xiàn)程終止:
pthread_join (pthread_t thread, void** threadreturn);

3.線(xiàn)程通信

線(xiàn)程互斥
互斥意味著(zhù)“排它”,即兩個(gè)線(xiàn)程不能同時(shí)進(jìn)入被互斥保護的代碼。Linux下可以通過(guò)pthread_mutex_t 定義互斥體機制完成多線(xiàn)程的互斥操作,該機制的作用是對某個(gè)需要互斥的部分,在進(jìn)入時(shí)先得到互斥體,如果沒(méi)有得到互斥體,表明互斥部分被其它線(xiàn)程擁有,此時(shí)欲獲取互斥體的線(xiàn)程阻塞,直到擁有該互斥體的線(xiàn)程完成互斥部分的操作為止。
下面的代碼實(shí)現了對共享全局變量x 用互斥體mutex 進(jìn)行保護的目的:
int x; // 進(jìn)程中的全局變量
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL); //按缺省的屬性初始化互斥體變量mutex
pthread_mutex_lock(&mutex); // 給互斥體變量加鎖
… //對變量x 的操作
phtread_mutex_unlock(&mutex); // 給互斥體變量解除鎖
線(xiàn)程同步
同步就是線(xiàn)程等待某個(gè)事件的發(fā)生。只有當等待的事件發(fā)生線(xiàn)程才繼續執行,否則線(xiàn)程掛起并放棄處理器。當多個(gè)線(xiàn)程協(xié)作時(shí),相互作用的任務(wù)必須在一定的條件下同步。
Linux下的C語(yǔ)言編程有多種線(xiàn)程同步機制,最典型的是條件變量(condition variable)。pthread_cond_init用來(lái)創(chuàng )建一個(gè)條件變量,其函數原型為:
pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr);
pthread_cond_wait和pthread_cond_timedwait用來(lái)等待條件變量被設置,值得注意的是這兩個(gè)等待調用需要一個(gè)已經(jīng)上鎖的互斥體mutex,這是為了防止在真正進(jìn)入等待狀態(tài)之前別的線(xiàn)程有可能設置該條件變量而產(chǎn)生競爭。pthread_cond_wait的函數原型為:
pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
pthread_cond_broadcast用于設置條件變量,即使得事件發(fā)生,這樣等待該事件的線(xiàn)程將不再阻塞:
pthread_cond_broadcast (pthread_cond_t *cond) ;
pthread_cond_signal則用于解除某一個(gè)等待線(xiàn)程的阻塞狀態(tài):
pthread_cond_signal (pthread_cond_t *cond) ; 
pthread_cond_destroy 則用于釋放一個(gè)條件變量的資源。
在頭文件semaphore.h 中定義的信號量則完成了互斥體和條件變量的封裝,按照多線(xiàn)程程序設計中訪(fǎng)問(wèn)控制機制,控制對資源的同步訪(fǎng)問(wèn),提供程序設計人員更方便的調用接口。
sem_init(sem_t *sem, int pshared, unsigned int val);
這個(gè)函數初始化一個(gè)信號量sem 的值為val,參數pshared 是共享屬性控制,表明是否在進(jìn)程間共享。
sem_wait(sem_t *sem);
調用該函數時(shí),若sem為無(wú)狀態(tài),調用線(xiàn)程阻塞,等待信號量sem值增加(post )成為有信號狀態(tài);若sem為有狀態(tài),調用線(xiàn)程順序執行,但信號量的值減一。
sem_post(sem_t *sem);
調用該函數,信號量sem的值增加,可以從無(wú)信號狀態(tài)變?yōu)橛行盘枲顟B(tài)。

4.實(shí)例

下面我們還是以著(zhù)名的生產(chǎn)者/消費者問(wèn)題為例來(lái)闡述Linux線(xiàn)程的控制和通信。一組生產(chǎn)者線(xiàn)程與一組消費者線(xiàn)程通過(guò)緩沖區發(fā)生聯(lián)系。生產(chǎn)者線(xiàn)程將生產(chǎn)的產(chǎn)品送入緩沖區,消費者線(xiàn)程則從中取出產(chǎn)品。緩沖區有N 個(gè),是一個(gè)環(huán)形的緩沖池。

  1. #include <stdio.h> 
  2. #include <pthread.h> 
  3. #define BUFFER_SIZE 16 // 緩沖區數量 
  4. struct prodcons 
  5.   // 緩沖區相關(guān)數據結構 
  6.   int buffer[BUFFER_SIZE]; /* 實(shí)際數據存放的數組*/ 
  7.   pthread_mutex_t lock; /* 互斥體lock 用于對緩沖區的互斥操作 */ 
  8.   int readpos, writepos; /* 讀寫(xiě)指針*/ 
  9.   pthread_cond_t notempty; /* 緩沖區非空的條件變量 */ 
  10.   pthread_cond_t notfull; /* 緩沖區未滿(mǎn)的條件變量 */ 
  11. }; 
  12. /* 初始化緩沖區結構 */ 
  13. void init(struct prodcons *b) 
  14.   pthread_mutex_init(&b->lock, NULL); 
  15.   pthread_cond_init(&b->notempty, NULL); 
  16.   pthread_cond_init(&b->notfull, NULL); 
  17.   b->readpos = 0; 
  18.   b->writepos = 0; 
  19. /* 將產(chǎn)品放入緩沖區,這里是存入一個(gè)整數*/ 
  20. void put(struct prodcons *b, int data) 
  21.   pthread_mutex_lock(&b->lock); 
  22.   /* 等待緩沖區未滿(mǎn)*/ 
  23.   if ((b->writepos + 1) % BUFFER_SIZE == b->readpos) 
  24.   { 
  25.     pthread_cond_wait(&b->notfull, &b->lock); 
  26.   } 
  27.   /* 寫(xiě)數據,并移動(dòng)指針 */ 
  28.   b->buffer[b->writepos] = data; 
  29.   b->writepos++; 
  30.   if (b->writepos >  = BUFFER_SIZE) 
  31.     b->writepos = 0; 
  32.   /* 設置緩沖區非空的條件變量*/ 
  33.   pthread_cond_signal(&b->notempty); 
  34.   pthread_mutex_unlock(&b->lock); 
  35.  
  36. /* 從緩沖區中取出整數*/ 
  37. int get(struct prodcons *b) 
  38.   int data; 
  39.   pthread_mutex_lock(&b->lock); 
  40.   /* 等待緩沖區非空*/ 
  41.   if (b->writepos == b->readpos) 
  42.   { 
  43.     pthread_cond_wait(&b->notempty, &b->lock); 
  44.   } 
  45.   /* 讀數據,移動(dòng)讀指針*/ 
  46.   data = b->buffer[b->readpos]; 
  47.   b->readpos++; 
  48.   if (b->readpos >  = BUFFER_SIZE) 
  49.     b->readpos = 0; 
  50.   /* 設置緩沖區未滿(mǎn)的條件變量*/ 
  51.   pthread_cond_signal(&b->notfull); 
  52.   pthread_mutex_unlock(&b->lock); 
  53.   return data; 
  54.  
  55. /* 測試:生產(chǎn)者線(xiàn)程將1 到10000 的整數送入緩沖區,消費者線(xiàn) 
  56. 程從緩沖區中獲取整數,兩者都打印信息*/ 
  57. #define OVER ( - 1) 
  58. struct prodcons buffer; 
  59. void *producer(void *data) 
  60.   int n; 
  61.   for (n = 0; n < 10000; n++) 
  62.   { 
  63.     printf("%d --->\n", n); 
  64.     put(&buffer, n); 
  65.   } put(&buffer, OVER); 
  66.   return NULL; 
  67.  
  68. void *consumer(void *data) 
  69.   int d; 
  70.   while (1) 
  71.   { 
  72.     d = get(&buffer); 
  73.     if (d == OVER) 
  74.       break
  75.     printf("--->%d \n", d); 
  76.   } 
  77.   return NULL; 
  78.  
  79. int main(void
  80.   pthread_t th_a, th_b; 
  81.   void *retval; 
  82.   init(&buffer); 
  83.   /* 創(chuàng )建生產(chǎn)者和消費者線(xiàn)程*/ 
  84.   pthread_create(&th_a, NULL, producer, 0); 
  85.   pthread_create(&th_b, NULL, consumer, 0); 
  86.   /* 等待兩個(gè)線(xiàn)程結束*/ 
  87.   pthread_join(th_a, &retval); 
  88.   pthread_join(th_b, &retval); 
  89.   return 0; 

5.WIN32、VxWorks、Linux線(xiàn)程類(lèi)比

目前為止,筆者已經(jīng)創(chuàng )作了《基于嵌入式操作系統VxWorks的多任務(wù)并發(fā)程序設計》(《軟件報》2006年5~12期連載)、《深入淺出Win32多線(xiàn)程程序設計》(天極網(wǎng)技術(shù)專(zhuān)題)系列,我們來(lái)找出這兩個(gè)系列文章與本文的共通點(diǎn)。
看待技術(shù)問(wèn)題要瞄準其本質(zhì),不管是Linux、VxWorks還是WIN32,其涉及到多線(xiàn)程的部分都是那些內容,無(wú)非就是線(xiàn)程控制和線(xiàn)程通信,它們的許多函數只是名稱(chēng)不同,其實(shí)質(zhì)含義是等價(jià)的,下面我們來(lái)列個(gè)三大操作系統共同點(diǎn)詳細表單:

事項

WIN32

VxWorks

Linux

線(xiàn)程創(chuàng )建

CreateThread

taskSpawn

pthread_create

線(xiàn)程終止

執行完成后退出;線(xiàn)程自身調用ExitThread 函數即終止自己;被其他線(xiàn)程調用函數TerminateThread函數

執行完成后退出;由線(xiàn)程本身調用exit退出;被其他線(xiàn)程調用函數taskDelete終止

執行完成后退出;由線(xiàn)程本身調用pthread_exit退出;被其他線(xiàn)程調用函數pthread_cance終止

獲取線(xiàn)程ID

GetCurrentThreadId

taskIdSelf

pthread_self

創(chuàng )建互斥

CreateMutex

semMCreate

pthread_mutex_init

獲取互斥

WaitForSingleObject、

WaitForMultipleObjects

semTake

pthread_mutex_lock

釋放互斥

ReleaseMutex

semGive

phtread_mutex_unlock

創(chuàng )建信號量

CreateSemaphore

semBCreate、semCCreate

sem_init

等待信號量

WaitForSingleObject

semTake

sem_wait

釋放信號量

ReleaseSemaphore

semGive

sem_post


6.小結

本章講述了Linux下多線(xiàn)程的控制及線(xiàn)程間通信編程方法,給出了一個(gè)生產(chǎn)者/消費者的實(shí)例,并將Linux的多線(xiàn)程與WIN32、VxWorks多線(xiàn)程進(jìn)行了類(lèi)比,總結了一般規律。鑒于多線(xiàn)程編程已成為開(kāi)發(fā)并發(fā)應用程序的主流方法,學(xué)好本章的意義也便不言自明。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Linux下的多線(xiàn)程編程
Posix線(xiàn)程編程指南
pthread的各種同步機制
Linux系統下的多線(xiàn)程編程入門(mén)-開(kāi)發(fā)頻道-多線(xiàn)程-天極網(wǎng)
線(xiàn)程同步、條件變量、互斥鎖的使用
SDL封裝的系統操作
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久