程式扎記: [Phread Tutorial] Thread Creation and Termination

標籤

2012年3月5日 星期一

[Phread Tutorial] Thread Creation and Termination

翻譯自 這裡 
Preface : 
POSIX標準中支援的執行緒函式庫稱為 pthread,我們可以透過 pthread 結構與 pthread_create() 函數執行某個函數指標,以建立新的執行緒. 透過多執行緒的使用我們可以 : 
The POSIX thread libraries are a standards based thread API for C/C++. It allows one to spawn a new concurrent process flow. It is most effective on multi-processor or multi-core systems where the process flow can be scheduled to run on another processor thus gaining speed through parallel or distributed processing. Threads require less overhead than "forking" or spawning a new process because the system does not initialize a new system virtual memory space and environment for the process. While most effective on a multiprocessor system, gains are also found on uniprocessor systems which exploit latency in I/O and other system functions which may halt process execution. (One thread may execute while another is waiting for I/O or some other system latency.) Parallel programming technologies such as MPI and PVM are used in a distributed computing environment while threads are limited to a single computer system. All threads within a process share the same address space. A thread is spawned by defining a function and its arguments which will be processed in the thread. The purpose of using the POSIX thread library in your software is to execute software faster.


Thread Basics : 
執行緒的操作包含 線程的建立 , 中止, 同步(joins,blocking), 排程, 資料處理與程序的互相溝通. 所有從同一個程序衍生出來的線程會有相同的記憶體位置空間並分享 : 
* Process instructions
* Most data
* open files (descriptors)
* signals and signal handlers
* current working directory
* User and group id

每隻線程有獨立的 : 
* Thread ID
* set of registers, stack pointer
* stack for local variables, return addresses
* signal mask
* priority
* Return value: errno

Thread Creation and Termination : 
底下我們會寫個簡單範例示範如何使用建立 pthread, 同步 pthread. 先來看看代碼 pthread1.c : 
- pthread1.c :
  1. #include   
  2. #include   
  3. #include   
  4.   
  5. void *print_message_function(void *ptr);  
  6.   
  7. main()  
  8. {  
  9.   pthread_t thread1, thread2;  
  10.   char *message1 = "Thread 1";  
  11.   char *message2 = "Thread 2";  
  12.   int iret1, iret2;  
  13.   
  14.   /*Create independent threads each of wich will execute function*/  
  15.   iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1);  
  16.   iret1 = pthread_create(&thread2, NULL, print_message_function, (void*) message2);  
  17.   
  18.   /* Wait till threads are complete before main continues. Unless we */  
  19.   /* wait we run the risk of executing an exit which will terminate */  
  20.   /* the process and all threads before the threads have completed.*/  
  21.   
  22.   pthread_join(thread1, NULL);  
  23.   pthread_join(thread2, NULL);  
  24.   
  25.   printf("Thread 1 returns: %d\n", iret1);  
  26.   printf("Thread 2 returns: %d\n", iret2);  
  27.   exit(0);  
  28. }  
  29.   
  30. void *print_message_function(void *ptr)  
  31. {  
  32.   char *message;  
  33.   message = (char*)ptr;  
  34.   printf("%s \n", message);  
  35. }  

接著你可以如下編譯程式, 並執行它 : 
$ gcc -lpthread pthread1.c -o pthread1 # 編譯 pthread1.c 並產生執行檔 pthread1
$ ./pthread1 # 執行編譯後的執行檔
Thread 2
Thread 1
Thread 1 returns: 0
Thread 2 returns: 0

代碼說明 : 
在這個範例程式 (pthread1.c) 兩隻 pthread 執行同一個函式但傳入不同參數. 你可以透過執行 pthread_exit 來終止 pthread. 或是在 pthread 執行的函式 return 也可以達成同樣目的. 在上面範例使用函式 pthread_create 來建立 pthread : 
  1. int pthread_create(pthread_t * thread,   
  2.                        const pthread_attr_t * attr,  
  3.                        void * (*start_routine)(void *),   
  4.                        void *arg);  
參數說明 : 
- thread : returns the thread id. (unsigned long int defined in bits/pthreadtypes.h)
- attr : Set to NULL if default thread attributes are used. (else define members of the struct pthread_attr_t defined in bits/pthreadtypes.h) Attributes include:
* detached state (joinable? Default: PTHREAD_CREATE_JOINABLE. Other option: PTHREAD_CREATE_DETACHED)
* scheduling policy (real-time? PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)
* scheduling parameter
* inheritsched attribute (Default: PTHREAD_EXPLICIT_SCHED Inherit from parent thread: PTHREAD_INHERIT_SCHED)
* scope (Kernel threads: PTHREAD_SCOPE_SYSTEM User threads: PTHREAD_SCOPE_PROCESS Pick one or the other not both.)
* guard size
* stack address (See unistd.h and bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)
* stack size (default minimum PTHREAD_STACK_SIZE set in pthread.h)

- void * (*start_routine) : pointer to the function to be executed by threaded. Function has a single argument: pointer to void.
- *arg : pointer to argument of function. To pass multiple arguments, send a pointer to a structure.

透過函式 pthread_join 可以讓 pthreads 間互相等待, 這裡是用來避免 main 函式過早結束 : 
  1. int pthread_join(pthread_t th, void **thread_return);  
參數說明 : 
- th : thread suspended until the thread identified by th terminates, either by calling pthread_exit() or by being cancelled.
- thread_return : If thread_return is not NULL, the return value of th is stored in the location pointed to by thread_return.

補充說明 : 
Thread Synchronization 
Thread Scheduling 
Thread Pitfalls 
Thread Debugging 
Thread Man Pages

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!