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

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

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

開(kāi)通VIP
POSIX 多線(xiàn)程程序設計
線(xiàn)程管理(Thread Management) 
創(chuàng )建和結束線(xiàn)程 
函數: 
pthread_create (thread,attr,start_routine,arg) 
pthread_exit (status) 
pthread_attr_init (attr) 
pthread_attr_destroy (attr) 
創(chuàng )建線(xiàn)程: 
最初,main函數包含了一個(gè)缺省的線(xiàn)程。其它線(xiàn)程則需要程序員顯式地創(chuàng )建。 
pthread_create 創(chuàng )建一個(gè)新線(xiàn)程并使之運行起來(lái)。該函數可以在程序的任何地方調用。 
pthread_create參數: 
thread:返回一個(gè)不透明的,唯一的新線(xiàn)程標識符。 
attr:不透明的線(xiàn)程屬性對象??梢灾付ㄒ粋€(gè)線(xiàn)程屬性對象,或者NULL為缺省值。 
start_routine:線(xiàn)程將會(huì )執行一次的C函數。 
arg: 傳遞給start_routine單個(gè)參數,傳遞時(shí)必須轉換成指向void的指針類(lèi)型。沒(méi)有參數傳遞時(shí),可設置為NULL。 
一個(gè)進(jìn)程可以創(chuàng )建的線(xiàn)程最大數量取決于系統實(shí)現。 
一旦創(chuàng )建,線(xiàn)程就稱(chēng)為peers,可以創(chuàng )建其它線(xiàn)程。線(xiàn)程之間沒(méi)有指定的結構和依賴(lài)關(guān)系。 


Q:一個(gè)線(xiàn)程被創(chuàng )建后,怎么知道操作系統何時(shí)調度該線(xiàn)程使之運行? 
A:除非使用了Pthreads的調度機制,否則線(xiàn)程何時(shí)何地被執行取決于操作系統的實(shí)現。強壯的程序應該不依賴(lài)于線(xiàn)程執行的順序。

線(xiàn)程屬性: 
線(xiàn)程被創(chuàng )建時(shí)會(huì )帶有默認的屬性。其中的一些屬性可以被程序員用線(xiàn)程屬性對象來(lái)修改。 
pthread_attr_init 和 pthread_attr_destroy用于初始化/銷(xiāo)毀先成屬性對象。 
其它的一些函數用于查詢(xún)和設置線(xiàn)程屬性對象的指定屬性。 
一些屬性下面將會(huì )討論。 
結束終止: 
結束線(xiàn)程的方法有一下幾種: 
線(xiàn)程從主線(xiàn)程(main函數的初始線(xiàn)程)返回。 
線(xiàn)程調用了pthread_exit函數。 
其它線(xiàn)程使用 pthread_cancel函數結束線(xiàn)程。 
調用exec或者exit函數,整個(gè)進(jìn)程結束。 
pthread_exit用于顯式退出線(xiàn)程。典型地,pthread_exit()函數在線(xiàn)程完成工作時(shí),不在需要時(shí)候被調用,退出線(xiàn)程。 
如果main()在其他線(xiàn)程創(chuàng )建前用pthread_exit()退出了,其他線(xiàn)程將會(huì )繼續執行。否則,他們會(huì )隨著(zhù)main的結束而終止。 
程序員可以可選擇的指定終止狀態(tài),當任何線(xiàn)程連接(join)該線(xiàn)程時(shí),該狀態(tài)就返回給連接(join)該線(xiàn)程的線(xiàn)程。 
清理:pthread_exit()函數并不會(huì )關(guān)閉文件,任何在線(xiàn)程中打開(kāi)的文件將會(huì )一直處于打開(kāi)狀態(tài),知道線(xiàn)程結束。 
討論:對于正常退出,可以免于調用pthread_exit()。當然,除非你想返回一個(gè)返回值。然而,在main中,有一個(gè)問(wèn)題,就是當main結束時(shí),其它線(xiàn)程還沒(méi)有被創(chuàng )建。如果此時(shí)沒(méi)有顯式的調用pthread_exit(),當main結束時(shí),進(jìn)程(和所有線(xiàn)程)都會(huì )終止??梢栽趍ain中調用pthread_exit(),此時(shí)盡管在main中已經(jīng)沒(méi)有可執行的代碼了,進(jìn)程和所有線(xiàn)程將保持存活狀態(tài),。 
--------------------------------------------------------------------------------
例子: Pthread 創(chuàng )建和終止 
該例用pthread_create()創(chuàng )建了5個(gè)線(xiàn)程。每一個(gè)線(xiàn)程都會(huì )打印一條“Hello World”的消息,然后調用pthread_exit()終止線(xiàn)程。 
Example Code - Pthread Creation and Termination 
#include <pthread.h> 
#include <stdio.h> 
#define NUM_THREADS     5 
void *PrintHello(void *threadid) 
{ 
   int tid; 
   tid = (int)threadid; 
   printf("Hello World! It's me, thread #%d!\n", tid); 
   pthread_exit(NULL); 
} 
int main (int argc, char *argv[]) 
{ 
   pthread_t threads[NUM_THREADS]; 
   int rc, t; 
   for(t=0; t<NUM_THREADS; t++){ 
      printf("In main: creating thread %d\n", t); 
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); 
      if (rc){ 
         printf("ERROR; return code from pthread_create() is %d\n", rc); 
         exit(-1); 
      } 
   } 
   pthread_exit(NULL); 
} 

線(xiàn)程管理 
向線(xiàn)程傳遞參數 
pthread_create()函數允許程序員想線(xiàn)程的start routine傳遞一個(gè)參數。當多個(gè)參數需要被傳遞時(shí),可以通過(guò)定義一個(gè)結構體包含所有要傳的參數,然后用pthread_create()傳遞一個(gè)指向改結構體的指針,來(lái)打破傳遞參數的個(gè)數的限制。 
所有參數都應該傳引用傳遞并轉化成(void*)。 
   
Q:怎樣安全地向一個(gè)新創(chuàng )建的線(xiàn)程傳遞數據? 
A:確保所傳遞的數據是線(xiàn)程安全的(不能被其他線(xiàn)程修改)。下面三個(gè)例子演示了那個(gè)應該和那個(gè)不應該。 

Example 1 - Thread Argument Passing 
下面的代碼片段演示了如何向一個(gè)線(xiàn)程傳遞一個(gè)簡(jiǎn)單的整數。主線(xiàn)程為每一個(gè)線(xiàn)程使用一個(gè)唯一的數據結構,確保每個(gè)線(xiàn)程傳遞的參數是完整的。 
--------------------------------------------------------------------------------
int *taskids[NUM_THREADS]; 
for(t=0; t<NUM_THREADS; t++) 
{ 
   taskids[t] = (int *) malloc(sizeof(int)); 
   *taskids[t] = t; 
   printf("Creating thread %d\n", t); 
   rc = pthread_create(&threads[t], NULL, PrintHello, 
        (void *) taskids[t]); 
   ... 
} 

Example 2 - Thread Argument Passing 
例子展示了用結構體向線(xiàn)程設置/傳遞參數。每個(gè)線(xiàn)程獲得一個(gè)唯一的結構體實(shí)例。 
--------------------------------------------------------------------------------
struct thread_data{ 
   int thread_id; 
   int sum; 
   char *message; 
}; 
struct thread_data thread_data_array[NUM_THREADS]; 
void *PrintHello(void *threadarg) 
{ 
   struct thread_data *my_data; 
   ... 
   my_data = (struct thread_data *) threadarg; 
   taskid = my_data->thread_id; 
   sum = my_data->sum; 
   hello_msg = my_data->message; 
   ... 
} 
int main (int argc, char *argv[]) 
{ 
   ... 
   thread_data_array[t].thread_id = t; 
   thread_data_array[t].sum = sum; 
   thread_data_array[t].message = messages[t]; 
   rc = pthread_create(&threads[t], NULL, PrintHello, 
        (void *) &thread_data_array[t]); 
   ... 
} 

Example 3 - Thread Argument Passing (Incorrect) 
例子演示了錯誤地傳遞參數。循環(huán)會(huì )在線(xiàn)程訪(fǎng)問(wèn)傳遞的參數前改變傳遞給線(xiàn)程的地址的內容。 
--------------------------------------------------------------------------------
int rc, t; 
for(t=0; t<NUM_THREADS; t++) 
{ 
   printf("Creating thread %d\n", t); 
   rc = pthread_create(&threads[t], NULL, PrintHello, 
        (void *) &t); 
   ... 
} 

線(xiàn)程管理 
連接(Joining)和分離(Detaching)線(xiàn)程 
函數: 
pthread_join (threadid,status) 
pthread_detach (threadid,status) 
pthread_attr_setdetachstate (attr,detachstate) 
pthread_attr_getdetachstate (attr,detachstate) 
連接: 
“連接”是一種在線(xiàn)程間完成同步的方法。例如: 
pthread_join()函數阻賽調用線(xiàn)程知道threadid所指定的線(xiàn)程終止。 
如果在目標線(xiàn)程中調用pthread_exit(),程序員可以在主線(xiàn)程中獲得目標線(xiàn)程的終止狀態(tài)。 
連接線(xiàn)程只能用pthread_join()連接一次。若多次調用就會(huì )發(fā)生邏輯錯誤。 
兩種同步方法,互斥量(mutexes)和條件變量(condition variables),稍后討論。 
可連接(Joinable or Not)? 
當一個(gè)線(xiàn)程被創(chuàng )建,它有一個(gè)屬性定義了它是可連接的(joinable)還是分離的(detached)。只有是可連接的線(xiàn)程才能被連接(joined),若果創(chuàng )建的線(xiàn)程是分離的,則不能連接。 
POSIX標準的最終草案指定了線(xiàn)程必須創(chuàng )建成可連接的。然而,并非所有實(shí)現都遵循此約定。 
使用pthread_create()的attr參數可以顯式的創(chuàng )建可連接或分離的線(xiàn)程,典型四步如下: 
聲明一個(gè)pthread_attr_t數據類(lèi)型的線(xiàn)程屬性變量 
用 pthread_attr_init()初始化改屬性變量 
用pthread_attr_setdetachstate()設置可分離狀態(tài)屬性 
完了后,用pthread_attr_destroy()釋放屬性所占用的庫資源 
分離(Detaching): 
pthread_detach()可以顯式用于分離線(xiàn)程,盡管創(chuàng )建時(shí)是可連接的。 
沒(méi)有與pthread_detach()功能相反的函數 
建議: 
若線(xiàn)程需要連接,考慮創(chuàng )建時(shí)顯式設置為可連接的。因為并非所有創(chuàng )建線(xiàn)程的實(shí)現都是將線(xiàn)程創(chuàng )建為可連接的。 
若事先知道線(xiàn)程從不需要連接,考慮創(chuàng )建線(xiàn)程時(shí)將其設置為可分離狀態(tài)。一些系統資源可能需要釋放。 
--------------------------------------------------------------------------------
例子: Pthread Joining 
Example Code - Pthread Joining 
這個(gè)例子演示了用Pthread join函數去等待線(xiàn)程終止。因為有些實(shí)現并不是默認創(chuàng )建線(xiàn)程是可連接狀態(tài),例子中顯式地將其創(chuàng )建為可連接的。 
--------------------------------------------------------------------------------
#include <pthread.h> 
#include <stdio.h> 
#define NUM_THREADS    3 
void *BusyWork(void *null) 
{ 
   int i; 
   double result=0.0; 
   for (i=0; i<1000000; i++) 
   { 
     result = result + (double)random(); 
   } 
   printf("result = %e\n",result); 
   pthread_exit((void *) 0); 
} 
int main (int argc, char *argv[]) 
{ 
   pthread_t thread[NUM_THREADS]; 
   pthread_attr_t attr; 
   int rc, t; 
   void *status; 
    /* Initialize and set thread detached attribute */ 
   pthread_attr_init(&attr); 
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
    for(t=0; t<NUM_THREADS; t++) 
   { 
      printf("Creating thread %d\n", t); 
      rc = pthread_create(&thread[t], &attr, BusyWork, NULL); 
      if (rc) 
      { 
         printf("ERROR; return code from pthread_create() 
                is %d\n", rc); 
         exit(-1); 
      } 
   } 
    /* Free attribute and wait for the other threads */ 
   pthread_attr_destroy(&attr); 
   for(t=0; t<NUM_THREADS; t++) 
   { 
      rc = pthread_join(thread[t], &status); 
      if (rc) 
      { 
         printf("ERROR; return code from pthread_join() 
                is %d\n", rc); 
         exit(-1); 
      } 
      printf("Completed join with thread %d status= %ld\n",t, (long)status); 
   } 
    pthread_exit(NULL); 
} 

線(xiàn)程管理 
棧管理 
函數: 
pthread_attr_getstacksize (attr, stacksize) 
pthread_attr_setstacksize (attr, stacksize) 
pthread_attr_getstackaddr (attr, stackaddr) 
pthread_attr_setstackaddr (attr, stackaddr) 
防止棧問(wèn)題: 
POSIX標準并沒(méi)有指定線(xiàn)程棧的大小,依賴(lài)于實(shí)現并隨實(shí)現變化。 
很容易超出默認的棧大小,常見(jiàn)結果:程序終止或者數據損壞。 
安全和可移植的程序應該不依賴(lài)于默認的棧限制,但是取而代之的是用pthread_attr_setstacksize分配足夠的棧大小。 
pthread_attr_getstackaddr和pthread_attr_setstackaddr函數可以被程序用于將棧設置在指定的內存區域。 
在LC上的一些實(shí)際例子: 
默認棧大小經(jīng)常變化很大,最大值也變化很大,可能會(huì )依賴(lài)于每個(gè)節點(diǎn)的線(xiàn)程數目。 
Node
Architecture 
#CPUs 
Memory (GB) 
Default Size
(bytes) 
AMD Opteron 
8 
16 
2,097,152 
Intel IA64 
4 
8 
33,554,432 
Intel IA32 
2 
4 
2,097,152 
IBM Power5 
8 
32 
196,608 
IBM Power4 
8 
16 
196,608 
IBM Power3 
16 
16 
98,304 
--------------------------------------------------------------------------------
例子: 棧管理 
Example Code - Stack Management 
這個(gè)例子演示了如何去查詢(xún)和設定線(xiàn)程棧大小。 
--------------------------------------------------------------------------------
#include <pthread.h> 
#include <stdio.h> 
#define NTHREADS 4 
#define N 1000 
#define MEGEXTRA 1000000 

pthread_attr_t attr; 

void *dowork(void *threadid) 
{ 
   double A[N][N]; 
   int i,j,tid; 
   size_t mystacksize; 
    tid = (int)threadid; 
   pthread_attr_getstacksize (&attr, &mystacksize); 
   printf("Thread %d: stack size = %li bytes \n", tid, mystacksize); 
   for (i=0; i<N; i++) 
     for (j=0; j<N; j++) 
      A[i][j] = ((i*j)/3.452) + (N-i); 
   pthread_exit(NULL); 
} 

int main(int argc, char *argv[]) 
{ 
   pthread_t threads[NTHREADS]; 
   size_t stacksize; 
   int rc, t; 

   pthread_attr_init(&attr); 
   pthread_attr_getstacksize (&attr, &stacksize); 
   printf("Default stack size = %li\n", stacksize); 
   stacksize = sizeof(double)*N*N+MEGEXTRA; 
   printf("Amount of stack needed per thread = %li\n",stacksize); 
   pthread_attr_setstacksize (&attr, stacksize); 
   printf("Creating threads with stack size = %li bytes\n",stacksize); 
   for(t=0; t<NTHREADS; t++){ 
      rc = pthread_create(&threads[t], &attr, dowork, (void *)t); 
      if (rc){ 
         printf("ERROR; return code from pthread_create() is %d\n", rc); 
         exit(-1); 
      } 
   } 
   printf("Created %d threads.\n", t); 
   pthread_exit(NULL); 
} 

線(xiàn)程管理 
其他各種函數: 
pthread_self () 
pthread_equal (thread1,thread2) 
pthread_self返回調用該函數的線(xiàn)程的唯一,系統分配的線(xiàn)程ID。 
pthread_equal比較兩個(gè)線(xiàn)程ID,若不同返回0,否則返回非0值。 
注意這兩個(gè)函數中的線(xiàn)程ID對象是不透明的,不是輕易能檢查的。因為線(xiàn)程ID是不透明的對象,所以C語(yǔ)言的==操作符不能用于比較兩個(gè)線(xiàn)程ID。 
pthread_once (once_control, init_routine) 
pthread_once 在一個(gè)進(jìn)程中僅執行一次init_routine。任何線(xiàn)程第一次調用該函數會(huì )執行給定的init_routine,不帶參數,任何后續調用都沒(méi)有效果。 
init_routine函數一般是初始化的程序 
once_control參數是一個(gè)同步結構體,需要在調用pthread_once前初始化。例如: 
pthread_once_t once_control = PTHREAD_ONCE_INIT; 
互斥量(Mutex Variables) 
概述 
互斥量(Mutex)是“mutual exclusion”的縮寫(xiě)?;コ饬渴菍?shí)現線(xiàn)程同步,和保護同時(shí)寫(xiě)共享數據的主要方法 
互斥量對共享數據的保護就像一把鎖。在Pthreads中,任何時(shí)候僅有一個(gè)線(xiàn)程可以鎖定互斥量,因此,當多個(gè)線(xiàn)程嘗試去鎖定該互斥量時(shí)僅有一個(gè)會(huì )成功。直到鎖定互斥量的線(xiàn)程解鎖互斥量后,其他線(xiàn)程才可以去鎖定互斥量。線(xiàn)程必須輪著(zhù)訪(fǎng)問(wèn)受保護數據。 
互斥量可以防止“競爭”條件。下面的例子是一個(gè)銀行事務(wù)處理時(shí)發(fā)生了競爭條件: 
Thread 1 
Thread 2 
Balance 
Read balance: $1000 
   
$1000 
   
Read balance: $1000 
$1000 
   
Deposit $200 
$1000 
Deposit $200 
   
$1000 
Update balance $1000+$200 
   
$1200 
   
Update balance $1000+$200 
$1200 

上面的例子,當一個(gè)線(xiàn)程使用共享數據資源時(shí),應該用一個(gè)互斥量去鎖定“Balance”。 
一個(gè)擁有互斥量的線(xiàn)程經(jīng)常用于更新全局變量。確保了多個(gè)線(xiàn)程更新同樣的變量以安全的方式運行,最終的結果和一個(gè)線(xiàn)程處理的結果是相同的。這個(gè)更新的變量屬于一個(gè)“臨界區(critical section)”。 
使用互斥量的典型順序如下: 
創(chuàng )建和初始一個(gè)互斥量 
多個(gè)線(xiàn)程嘗試去鎖定該互斥量 
僅有一個(gè)線(xiàn)程可以成功鎖定改互斥量 
鎖定成功的線(xiàn)程做一些處理 
線(xiàn)程解鎖該互斥量 
另外一個(gè)線(xiàn)程獲得互斥量,重復上述過(guò)程 
最后銷(xiāo)毀互斥量 
當多個(gè)線(xiàn)程競爭同一個(gè)互斥量時(shí),失敗的線(xiàn)程會(huì )阻塞在lock調用處??梢杂?#8220;trylock”替換“lock”,則失敗時(shí)不會(huì )阻塞。 
當保護共享數據時(shí),程序員有責任去確認是否需要使用互斥量。如,若四個(gè)線(xiàn)程會(huì )更新同樣的數據,但僅有一個(gè)線(xiàn)程用了互斥量,則數據可能會(huì )損壞。 
互斥量(Mutex Variables) 
創(chuàng )建和銷(xiāo)毀互斥量 
函數: 
pthread_mutex_init (mutex,attr) 
pthread_mutex_destroy (mutex) 
pthread_mutexattr_init (attr) 
pthread_mutexattr_destroy (attr) 
用法: 
互斥量必須用類(lèi)型pthread_mutex_t類(lèi)型聲明,在使用前必須初始化,這里有兩種方法可以初始化互斥量: 
聲明時(shí)靜態(tài)地,如:
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;   
動(dòng)態(tài)地用pthread_mutex_init()函數,這種方法允許設定互斥量的屬性對象attr。 
互斥量初始化后是解鎖的。 
attr對象用于設置互斥量對象的屬性,使用時(shí)必須聲明為pthread_mutextattr_t類(lèi)型,默認值可以是NULL。Pthreads標準定義了三種可選的互斥量屬性: 

協(xié)議(Protocol): 指定了協(xié)議用于阻止互斥量的優(yōu)先級改變 
優(yōu)先級上限(Prioceiling):指定互斥量的優(yōu)先級上限 
進(jìn)程共享(Process-shared):指定進(jìn)程共享互斥量 
注意所有實(shí)現都提供了這三個(gè)可先的互斥量屬性。 
pthread_mutexattr_init()和pthread_mutexattr_destroy()函數分別用于創(chuàng )建和銷(xiāo)毀互斥量屬性對象。 
pthread_mutex_destroy()應該用于釋放不需要再使用的互斥量對象。 
互斥量(Mutex Variables) 
鎖定和解鎖互斥量 
函數: 
pthread_mutex_lock (mutex) 
pthread_mutex_trylock (mutex) 
pthread_mutex_unlock (mutex) 
用法: 
線(xiàn)程用pthread_mutex_lock()函數去鎖定指定的mutex變量,若該mutex已經(jīng)被另外一個(gè)線(xiàn)程鎖定了,該調用將會(huì )阻塞線(xiàn)程直到mutex被解鎖。 
pthread_mutex_trylock() will attempt to lock a mutex. However, if the mutex is already locked, the routine will return immediately with a "busy" error code. This routine may be useful in   
pthread_mutex_trylock()嘗試著(zhù)去鎖定一個(gè)互斥量,然而,若互斥量已被鎖定,程序會(huì )立刻返回并返回一個(gè)忙錯誤值。該函數在優(yōu)先級改變情況下阻止死鎖是非常有用的。 
線(xiàn)程可以用pthread_mutex_unlock()解鎖自己占用的互斥量。在一個(gè)線(xiàn)程完成對保護數據的使用,而其它線(xiàn)程要獲得互斥量在保護數據上工作時(shí),可以調用該函數。若有一下情形則會(huì )發(fā)生錯誤: 
互斥量已經(jīng)被解鎖 
互斥量被另一個(gè)線(xiàn)程占用 
互斥量并沒(méi)有多么“神奇”的,實(shí)際上,它們就是參與的線(xiàn)程的“君子約定”。寫(xiě)代碼時(shí)要確信正確地鎖定,解鎖互斥量。下面演示了一種邏輯錯誤: 
·                    Thread 1     Thread 2     Thread 3 
·                    Lock         Lock          
·                    A = 2        A = A+1      A = A*B 
·                    Unlock       Unlock     
   
Q:有多個(gè)線(xiàn)程等待同一個(gè)鎖定的互斥量,當互斥量被解鎖后,那個(gè)線(xiàn)程會(huì )第一個(gè)鎖定互斥量? 
A:除非線(xiàn)程使用了優(yōu)先級調度機制,否則,線(xiàn)程會(huì )被系統調度器去分配,那個(gè)線(xiàn)程會(huì )第一個(gè)鎖定互斥量是隨機的。 
--------------------------------------------------------------------------------
例子:使用互斥量 
Example Code - Using Mutexes 
例程演示了線(xiàn)程使用互斥量處理一個(gè)點(diǎn)積(dot product)計算。主數據通過(guò)一個(gè)可全局訪(fǎng)問(wèn)的數據結構被所有線(xiàn)程使用,每個(gè)線(xiàn)程處理數據的不同部分,主線(xiàn)程等待其他線(xiàn)程完成計算并輸出結果。 
--------------------------------------------------------------------------------
#include <pthread.h> 
#include <stdio.h> 
#include <malloc.h> 
/*    
The following structure contains the necessary information   
to allow the function "dotprod" to access its input data and 
place its output into the structure.   
*/ 
typedef struct 
{ 
   double      *a; 
   double      *b; 
   double     sum; 
   int     veclen; 
} DOTDATA; 
/* Define globally accessible variables and a mutex */ 
#define NUMTHRDS 4 
#define VECLEN 100 
   DOTDATA dotstr; 
   pthread_t callThd[NUMTHRDS]; 
   pthread_mutex_t mutexsum; 
/* 
The function dotprod is activated when the thread is created. 
All input to this routine is obtained from a structure 
of type DOTDATA and all output from this function is written into 
this structure. The benefit of this approach is apparent for the 
multi-threaded program: when a thread is created we pass a single 
argument to the activated function - typically this argument 
is a thread number. All the other information required by the 
function is accessed from the globally accessible structure. 
*/ 
void *dotprod(void *arg) 
{ 
    /* Define and use local variables for convenience */ 
    int i, start, end, offset, len ; 
   double mysum, *x, *y; 
   offset = (int)arg; 
      
   len = dotstr.veclen; 
   start = offset*len; 
   end   = start + len; 
   x = dotstr.a; 
   y = dotstr.b; 
    /* 
   Perform the dot product and assign result 
   to the appropriate variable in the structure. 
   */ 
    mysum = 0; 
   for (i=start; i<end ; i++) 
    { 
      mysum += (x[i] * y[i]); 
    } 
    /* 
   Lock a mutex prior to updating the value in the shared 
   structure, and unlock it upon updating. 
   */ 
   pthread_mutex_lock (&mutexsum); 
   dotstr.sum += mysum; 
   pthread_mutex_unlock (&mutexsum); 
    pthread_exit((void*) 0); 
} 
/* 
The main program creates threads which do all the work and then 
print out result upon completion. Before creating the threads, 
the input data is created. Since all threads update a shared structure, 
we need a mutex for mutual exclusion. The main thread needs to wait for 
all threads to complete, it waits for each one of the threads. We specify 
a thread attribute value that allow the main thread to join with the 
threads it creates. Note also that we free up handles when they are 
no longer needed. 
*/ 
int main (int argc, char *argv[]) 
{ 
   int i; 
   double *a, *b; 
   void *status; 
   pthread_attr_t attr; 
    /* Assign storage and initialize values */ 
   a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 
   b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double)); 
   
   for (i=0; i<VECLEN*NUMTHRDS; i++) 
    { 
     a[i]=1.0; 
     b[i]=a[i]; 
    } 
    dotstr.veclen = VECLEN; 
   dotstr.a = a; 
   dotstr.b = b; 
   dotstr.sum=0; 
    pthread_mutex_init(&mutexsum, NULL); 
          
   /* Create threads to perform the dotproduct */ 
   pthread_attr_init(&attr); 
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
         for(i=0; i<NUMTHRDS; i++) 
        { 
        /* 
        Each thread works on a different set of data. 
        The offset is specified by 'i'. The size of 
        the data for each thread is indicated by VECLEN. 
        */ 
        pthread_create( &callThd[i], &attr, dotprod, (void *)i); 
        } 
         pthread_attr_destroy(&attr); 
         /* Wait on the other threads */ 
        for(i=0; i<NUMTHRDS; i++) 
        { 
          pthread_join( callThd[i], &status); 
        } 
    /* After joining, print out the results and cleanup */ 
   printf ("Sum = %f \n", dotstr.sum); 
   free (a); 
   free (b); 
   pthread_mutex_destroy(&mutexsum); 
   pthread_exit(NULL); 
}    
Serial version 
Pthreads version 

條件變量(Condition Variables) 
概述 
條件變量提供了另一種同步的方式?;コ饬客ㄟ^(guò)控制對數據的訪(fǎng)問(wèn)實(shí)現了同步,而條件變量允許根據實(shí)際的數據值來(lái)實(shí)現同步。 
沒(méi)有條件變量,程序員就必須使用線(xiàn)程去輪詢(xún)(可能在臨界區),查看條件是否滿(mǎn)足。這樣比較消耗資源,因為線(xiàn)程連續繁忙工作。條件變量是一種可以實(shí)現這種輪詢(xún)的方式。 
條件變量往往和互斥一起使用 
使用條件變量的代表性順序如下: 
主線(xiàn)程(Main Thread) 
o                                聲明和初始化需要同步的全局數據/變量(如“count”) 
o                                生命和初始化一個(gè)條件變量對象 
o                                聲明和初始化一個(gè)相關(guān)的互斥量 
o                                創(chuàng )建工作線(xiàn)程A和B 
Thread A 
o                                工作,一直到一定的條件滿(mǎn)足(如“count”等于一個(gè)指定的值) 
o                                鎖定相關(guān)互斥量并檢查全局變量的值 
o                                調用pthread_cond_wait()阻塞等待Thread-B的信號。注意pthread_cond_wait()能夠自動(dòng)地并且原子地解鎖相關(guān)的互斥量,以至于它可以被Thread-B使用。 
o                                當收到信號,喚醒線(xiàn)程,互斥量被自動(dòng),原子地鎖定。 
o                                顯式解鎖互斥量 
o                                繼續 
Thread B 
o                                工作 
o                                鎖定相關(guān)互斥量 
o                                改變Thread-A所等待的全局變量 
o                                檢查全局變量的值,若達到需要的條件,像Thread-A發(fā)信號。 
o                                解鎖互斥量 
o                                繼續 
Main Thread 
Join / Continue 

條件變量(Condition Variables) 
創(chuàng )建和銷(xiāo)毀條件變量 
Routines: 
pthread_cond_init (condition,attr) 
pthread_cond_destroy (condition) 
pthread_condattr_init (attr) 
pthread_condattr_destroy (attr) 
Usage: 
條件變量必須聲明為pthread_cond_t類(lèi)型,必須在使用前初始化。有兩種方式可以初始條件變量: 
聲明時(shí)靜態(tài)地。如:
pthread_cond_t myconvar = PTHREAD_COND_INITIALIZER;   
用pthread_cond_init()函數動(dòng)態(tài)地。創(chuàng )建的條件變量ID通過(guò)condition參數返回給調用線(xiàn)程。該方式允許設置條件變量對象的屬性,attr。 

可選的attr對象用于設定條件變量的屬性。僅有一個(gè)屬性被定義:線(xiàn)程共享(process-shared),可以使條件變量被其它進(jìn)程中的線(xiàn)程看到。若要使用屬性對象,必須定義為pthread_condattr_t類(lèi)型(可以指定為NULL設為默認)。 
注意所有實(shí)現都提供了線(xiàn)程共享屬性。 
pthread_condattr_init()和pthread_condattr_destroy()用于創(chuàng )建和銷(xiāo)毀條件變量屬性對象。 
條件變量不需要再使用時(shí),應用pthread_cond_destroy()釋放條件變量。 
條件變量(Condition Variables) 
在條件變量上等待(Waiting)和發(fā)送信號(Signaling) 
函數: 
pthread_cond_wait (condition,mutex) 
pthread_cond_signal (condition) 
pthread_cond_broadcast (condition) 
用法: 
pthread_cond_wait()阻塞調用線(xiàn)程直到指定的條件受信(signaled)。該函數應該在互斥量鎖定時(shí)調用,當在等待時(shí)會(huì )自動(dòng)解鎖互斥量。在信號被發(fā)送,線(xiàn)程被激活后,互斥量會(huì )自動(dòng)被鎖定,當線(xiàn)程結束時(shí),由程序員負責解鎖互斥量。 
pthread_cond_signal()函數用于向其他等待在條件變量上的線(xiàn)程發(fā)送信號(激活其它線(xiàn)程)。應該在互斥量被鎖定后調用。 
若不止一個(gè)線(xiàn)程阻塞在條件變量上,則應用pthread_cond_broadcast()向其它所以線(xiàn)程發(fā)生信號。 
在調用pthread_cond_wait()前調用pthread_cond_signal()會(huì )發(fā)生邏輯錯誤。 
使用這些函數時(shí)適當的鎖定和解鎖相關(guān)的互斥量是非常重要的。如: 
調用pthread_cond_wait()前鎖定互斥量失敗可能導致線(xiàn)程不會(huì )阻塞。 
調用pthread_cond_signal()后解鎖互斥量失敗可能會(huì )不允許相應的pthread_cond_wait()函數結束(保存阻塞)。 
--------------------------------------------------------------------------------
例子:使用條件變量 
Example Code - Using Condition Variables 
例子演示了使用Pthreads條件變量的幾個(gè)函數。主程序創(chuàng )建了三個(gè)線(xiàn)程,兩個(gè)線(xiàn)程工作,根系“count”變量。第三個(gè)線(xiàn)程等待count變量值達到指定的值。 
--------------------------------------------------------------------------------
#include <pthread.h> 
#include <stdio.h> 
#define NUM_THREADS 3 
#define TCOUNT 10 
#define COUNT_LIMIT 12 
int     count = 0; 
int     thread_ids[3] = {0,1,2}; 
pthread_mutex_t count_mutex; 
pthread_cond_t count_threshold_cv; 
void *inc_count(void *idp) 
{ 
int j,i; 
double result=0.0; 
int *my_id = idp; 
   for (i=0; i<TCOUNT; i++) { 
    pthread_mutex_lock(&count_mutex); 
    count++; 
     /* 
    Check the value of count and signal waiting thread when condition is 
    reached. Note that this occurs while mutex is locked. 
    */ 
    if (count == COUNT_LIMIT) { 
      pthread_cond_signal(&count_threshold_cv); 
      printf("inc_count(): thread %d, count = %d Threshold reached.\n", 
             *my_id, count); 
      } 
    printf("inc_count(): thread %d, count = %d, unlocking mutex\n", 
           *my_id, count); 
    pthread_mutex_unlock(&count_mutex); 
     /* Do some work so threads can alternate on mutex lock */ 
    for (j=0; j<1000; j++) 
      result = result + (double)random(); 
    } 
pthread_exit(NULL); 
} 
void *watch_count(void *idp) 
{ 
int *my_id = idp; 
   printf("Starting watch_count(): thread %d\n", *my_id); 
   /* 
Lock mutex and wait for signal. Note that the pthread_cond_wait 
routine will automatically and atomically unlock mutex while it waits. 
Also, note that if COUNT_LIMIT is reached before this routine is run by 
the waiting thread, the loop will be skipped to prevent pthread_cond_wait 
from never returning. 
*/ 
pthread_mutex_lock(&count_mutex); 
if (count<COUNT_LIMIT) { 
    pthread_cond_wait(&count_threshold_cv, &count_mutex); 
    printf("watch_count(): thread %d Condition signal 
           received.\n", *my_id); 
    } 
pthread_mutex_unlock(&count_mutex); 
pthread_exit(NULL); 
} 
int main (int argc, char *argv[]) 
{ 
int i, rc; 
pthread_t threads[3]; 
pthread_attr_t attr; 
   /* Initialize mutex and condition variable objects */ 
pthread_mutex_init(&count_mutex, NULL); 
pthread_cond_init (&count_threshold_cv, NULL); 
   /* For portability, explicitly create threads in a joinable state */ 
pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
pthread_create(&threads[0], &attr, inc_count, (void *)&thread_ids[0]); 
pthread_create(&threads[1], &attr, inc_count, (void *)&thread_ids[1]); 
pthread_create(&threads[2], &attr, watch_count, (void *)&thread_ids[2]); 
   /* Wait for all threads to complete */ 
for (i=0; i<NUM_THREADS; i++) { 
    pthread_join(threads[i], NULL); 
} 
printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS); 
   /* Clean up and exit */ 
pthread_attr_destroy(&attr); 
pthread_mutex_destroy(&count_mutex); 
pthread_cond_destroy(&count_threshold_cv); 
pthread_exit(NULL); 
} 


本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/future_fighter/archive/2009/02/05/3865071.aspx
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
【轉】POSIX線(xiàn)程庫條件變量的使用——Pthreads線(xiàn)程庫實(shí)例筆記4 - BlueClue's Blog - 博客園
線(xiàn)程通信
pthread
linux多線(xiàn)程編程,你還在用sleep么?用pthread
Posix線(xiàn)程編程指南
Linux下的多線(xiàn)程編程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

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