1. 程式人生 > >Linux下的多執行緒程式設計

Linux下的多執行緒程式設計

我們編譯此程式:
gcc example1.c -lpthread -o example1
執行example1,我們得到如下結果:
This is the main process.
This is a pthread.
This is the main process.
This is the main process.
This is a pthread.
This is a pthread.
再次執行,我們 可能得到如下結果:
This is a pthread.
This is the main process.
This is a pthread.
This is the main process.
This is a pthread.
This is the main process.

  前後兩次結果不一樣,這是兩個執行緒爭奪CPU資源的結果。上面的示例中,我們使用到了兩個函式,   pthread_create和pthread_join,並聲明瞭一個pthread_t型的變數。
  pthread_t在標頭檔案 /usr/include/bits/pthreadtypes.h中定義:
  typedef unsigned long int pthread_t;
  它是一個執行緒的識別符號。函式pthread_create用來建立一個執行緒,它的原型為:
  extern int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr,
  void *(*__start_routine) (void *), void *__arg));
  第一個 引數為指向執行緒識別符號的指標,第二個引數用來設定執行緒屬性,第三個引數是執行緒執行函式的起始地址,最後一個引數是執行函式的引數。這裡,我們的函式 thread不需要引數,所以最後一個引數設為空指標。第二個引數我們也設為空指標,這樣將生成預設屬性的執行緒。對執行緒屬性的設定和修改我們將在下一節闡 述。當建立執行緒成功時,函式返回0,若不為0則說明建立執行緒失敗,常見的錯誤返回程式碼為EAGAIN和EINVAL。前者表示系統限制建立新的執行緒,例如 執行緒數目過多了;後者表示第二個引數代表的執行緒屬性值非法。建立執行緒成功後,新建立的執行緒則執行引數三和引數四確定的函式,原來的執行緒則繼續執行下一行代 碼。
  函式pthread_join用來等待一個執行緒的結束。函式原型為:
  extern int pthread_join __P ((pthread_t __th, void **__thread_return));
  第一個引數為被等待的執行緒識別符號,第二個 引數為一個使用者定義的指標,它可以用來儲存被等待執行緒的返回值。這個函式是一個執行緒阻塞的函式,呼叫它的函式將一直等待到被等待的執行緒結束為止,當函式返 回時,被等待執行緒的資源被收回。一個執行緒的結束有兩種途徑,一種是象我們上面的例子一樣,函式結束了,呼叫它的執行緒也就結束了;另一種方式是通過函式 pthread_exit來實現。它的函式原型為:
  extern void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__));
  唯一的引數是函式的返回程式碼,只要 pthread_join中的第二個引數thread_return不是NULL,這個值將被傳遞給thread_return。最後要說明的是,一個線 程不能被多個執行緒等待,否則第一個接收到訊號的執行緒成功返回,其餘呼叫pthread_join的執行緒則返回錯誤程式碼ESRCH。
  在這一節 裡,我們編寫了一個最簡單的執行緒,並掌握了最常用的三個函式pthread_create,pthread_join和pthread_exit。下面, 我們來了解執行緒的一些常用屬性以及如何設定這些屬性。