POSIX執行緒程式設計起步(1)-Hello World (轉)
前言
在主機上,執行緒常常又被稱為“輕量級程式”,這種稱呼很簡單同時也便於理解,事實上,UNIX執行緒是從程式演變而來的。與程式相比,執行緒相當小,建立執行緒引起的開銷也相對較小。不僅如此,由於執行緒可以共享資源,而不像程式那樣擁有獨立的記憶體空間,所以使用執行緒也很節省記憶體。以後的幾篇文章,將重點講述POSIX 執行緒標準最常用的部分(主要基於其在DEC O/1 OS, V3.0上的實現)。
1.Hello World
建立程式所用的是pthread_create()。它的四個引數包括了:一個執行緒(pthread_t)變數的指標、一個執行緒屬性(pthread_attr_t)變數的指標、執行緒啟動時所要執行的函式指標以及傳遞給該函式的一個引數(void *)。
pthread_t a_thread;
pthread_attr_t a_thread_attribute;
void * thread_function(void *argument);
char *some_argument;
pthread_create( &a_thread, a_thread_attribute, thread_function, (void *)some_argument);
很多時候,執行緒屬性變數僅僅指定執行緒使用的最小棧。其實它有更豐富的含義,但現在的情況是,大多數應用建立新執行緒時值不過傳遞了一個PTHREAD_ATTR_DEFAULT,有時甚至只是NULL。用pthread_create()建立出的新執行緒,從指定的函式入口開始,這與建立程式不同:所有的程式都具有相同的執行序列。這樣設計的原因很簡單:如果所有的程式都從同一程式空間的同一處開始執行,那麼就會有多個程式對相同的共享資源執行相同的指令。
現在我們已經知道如何建立新執行緒,就讓我們來開始第一個多執行緒程式:用多個執行緒在螢幕上輸出“Hello World”。為了顯示執行緒的作用,我們將用到兩個執行緒:一個用來輸出“Hello”、另一個用來輸出“World”。為此,我們首先需要一個用於螢幕輸出的函式,新執行緒將從此函式開始執行。此外,我們還需要兩個執行緒(pthread_t)變數,用來建立新執行緒。當然,我們需要在pthread_create()的引數中指明每個新執行緒應該輸出的字串。請看以下程式碼:
void * print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
char *message1 = "Hello";
char *message2 = "World";
pthread_create( &thread1, pthread_attr_default,
print_message_function, (void*) message1);
pthread_create(&thread2, pthread_attr_default,
print_message_function, (void*) message2);
exit(0);
}
void * print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
printf("%s ", message);
}
這裡需要注意的是print_message_function()函式的原型,以及建立新執行緒時對引數型別的轉換。程式首先建立第一個新執行緒並將“Hello”作為引數傳遞,接著建立了另一個執行緒並傳遞“World”作為起始引數。我們希望第一個執行緒從printf_message_function()開始執行,在輸出“Hello”後結束,接著第二個執行緒在輸出“World”之後也同樣地結束。這樣的過程看起來似乎很合理,然而其中有兩處嚴重缺陷。
首先,不同的執行緒是並行執行的,並無先後次序。因此我們無法保證第一個新執行緒在第二執行緒之前輸出字串。其結果是,螢幕輸出可能是“Hello World”,也可能是“World Hello”。其次,與上述原因類似,父執行緒(姑且如此稱呼)有可能在兩個子執行緒輸出之前就執行了exit(0),這將導致整個程式結束——當然兩個子程式也就因此而結束了。其後果是螢幕上可能根本沒有輸出。為了解決第二個問題,我們可以用pthread_exit()來代替exit(),這樣兩個子程式就不會結束(因為該函式不會終止整個程式的執行)。
目前我們的小程式有兩個競爭條件,現在讓我們試著用比較笨的辦法來解決它們。首先,為了讓兩個子執行緒按照我們需要的順序執行,我們在建立第二個執行緒之前插入一個延遲。接著,為了保證在子執行緒結束之前父執行緒不退出,我們在父執行緒的尾部也插入一個延遲。請看下面的程式碼:
void * print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
char *message1 = "Hello";
char *message2 = "World";
pthread_create( &thread1, pthread_attr_default,
print_message_function, (void *) message1);
sleep(10);
pthread_create(&thread2, pthread_attr_default,
print_message_function, (void *) message2);
sleep(10);
exit(0);
}
void * print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
printf("%s", message);
pthread_exit(0);
}
令人遺憾的是,以上程式碼仍然不能達到我們的目的。利用延遲來進行執行緒同步是很不可靠的。我們目前遇到的同步問題本質上與分散式中的同步問題相同:我們永遠無法確知某一個執行緒將會在何時結束。
以上程式碼的缺陷不只是不可靠,事實上sleep()函式執行時,整個程式都在睡覺而不僅僅是父執行緒,這一點和exit()很像。當sleep()返回時,我們的程式仍然面對著相同的條件競爭。我們的新程式碼不僅沒有解決競爭問題,反而讓我們多花了20秒來等待程式結束。順便應該指出,如果想要對某一執行緒進行延遲,應該pthread_delay_np()函式(np意指non portable,不可移植),如下:
struct timespec delay;
delay.tv_sec = 2;
delay.tv_nsec = 0;
pthread_delay_np( &delay );
本節涉及的函式:
pthread_create(), pthread_exit(), pthread_delay_np().
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-960578/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- POSIX執行緒程式設計起步(2)-執行緒同步 (轉)執行緒程式設計
- Posix執行緒程式設計指南(1)-執行緒建立與取消 (轉)執行緒程式設計
- Posix執行緒程式設計指南(3)-執行緒同步 (轉)執行緒程式設計
- Posix執行緒程式設計指南(4)-執行緒終止 (轉)執行緒程式設計
- Posix執行緒程式設計指南(5)-Misc (轉)執行緒程式設計
- Posix執行緒程式設計指南(2)-執行緒私有資料 (轉)執行緒程式設計
- POSIX執行緒詳解 (轉)執行緒
- POSIX 執行緒詳解(3) (轉)執行緒
- POSIX執行緒詳解(2) (轉)執行緒
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- Cangjie—倉頡程式設計-Hello,World程式設計
- DELPHI下的多執行緒程式設計(1) (轉)執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- Go Web 程式設計之 Hello WorldGoWeb程式設計
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- java執行緒程式設計(一):執行緒基礎(轉)Java執行緒程式設計
- .NET多執行緒程式設計(4):執行緒池和非同步程式設計 (轉)執行緒程式設計非同步
- C#多執行緒程式設計(1):執行緒的啟動C#執行緒程式設計
- 計算機系統->Hello World的一生 | 程式如何執行計算機
- 漫畫:程式設計異聞錄 Hello World!程式設計
- Docker第一彈:下載執行hello-world程式Docker
- Java多執行緒程式設計入門(轉)Java執行緒程式設計
- 多執行緒程式設計執行緒程式設計
- 執行緒程式設計(一)執行緒程式設計
- Linux下第一個程式設計,hello world!Linux程式設計
- 第一個shell程式設計,輸出hello world!程式設計
- java多執行緒程式設計chap1-2Java執行緒程式設計
- C# Hello,World(1)
- 併發程式設計之多執行緒執行緒安全程式設計執行緒
- python多執行緒程式設計1— python對多執行緒的支援Python執行緒程式設計
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- ABAP程式Hello World
- Java多執行緒設計模式(1)Java執行緒設計模式
- 深入淺出Java多執行緒程式設計(轉)Java執行緒程式設計
- Linux下的多執行緒程式設計(轉)Linux執行緒程式設計
- DELPHI下的多執行緒程式設計(2) (轉)執行緒程式設計
- Java15 執行Hello,world竟然不用javac?Java
- JVM中的Hello World是如何執行的?JVM