歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 《APUE》:線程和fork

《APUE》:線程和fork

日期:2017/3/1 10:09:12   编辑:Linux編程

《Unix環境高級編程》這本書附帶了許多短小精美的小程序,我在閱讀此書的時候,將書上的代碼按照自己的理解重寫了一遍(大部分是抄書上的),加深一下自己的理解(純看書太困了,呵呵)。此例子在Ubuntu10.04上測試通過。

程序簡介:多線程的進程通過fork函數創建子進程時,如果要清除各種鎖的狀態,可以通過調用pthread_atfork函數建立fork處理程序。

  1. //《APUE》程序12-7:pthread_atfork實例
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <signal.h>
  6. #include <pthread.h>
  7. pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
  8. pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
  9. void prepare(void)
  10. {
  11. printf("preparing locks...\n");
  12. pthread_mutex_lock(&lock1);
  13. pthread_mutex_lock(&lock2);
  14. }
  15. void parent(void)
  16. {
  17. printf("parent unlocking locks...\n");
  18. pthread_mutex_unlock(&lock1);
  19. pthread_mutex_unlock(&lock2);
  20. }
  21. void child(void)
  22. {
  23. printf("child unlocking locks...\n");
  24. pthread_mutex_unlock(&lock1);
  25. pthread_mutex_unlock(&lock2);
  26. }
  27. void *thr_fn(void *fn)
  28. {
  29. printf("thread started...\n");
  30. pause();
  31. return 0;
  32. }
  33. int main(void)
  34. {
  35. pid_t pid;
  36. pthread_t tid;
  37. //BSD系統和MAC OS系統不支持pthread_atfork
  38. #if defined(BSD) || defined(MACOS)
  39. printf("pthread_atfork is unsupported\n");
  40. #else
  41. //見注解2
  42. pthread_atfork(prepare, parent, child);
  43. pthread_create(&tid, NULL, thr_fn, NULL);
  44. sleep(2);
  45. printf("parent about to fork...\n");
  46. pid = fork();
  47. if( 0 == pid )
  48. printf("child returned from fork\n");
  49. else
  50. printf("parent returned from fork\n");
  51. #endif
  52. return 0;
  53. }

運行示例(紅色字體的為輸入):

www.linuxidc.com @ubuntu:~/code$ gcc temp.c -lpthread -o temp
www.linuxidc.com @ubuntu:~/code$ ./temp

thread started...
parent about to fork...
preparing locks...
parent unlocking locks...
parent returned from fork
child unlocking locks...
child returned from fork

注解:
1:父進程通過fork創建了子進程。子進程不但繼承了父進程整個地址空間的副本,也繼承了所有的互斥量,讀寫鎖和條件變量的狀態,如果父進程包含多個線程,子進程在fork返回之後,如果不是緊接著使用exec的話,就要清理鎖狀態。
2:pthread_atfork最多可以安裝三個幫助清理鎖的函數。prepare函數將在fork創建子進程之前被調用,通常可以用來獲取進程中的所有鎖;parent在fork創建子進程後返回前在父進程中被調用,可以用來釋放父進程中的鎖;child在fork創建子進程後fork返回前在子進程中被調用,可以用來釋放子進程中的鎖。給這三個參數傳遞NULL,表示不調用該函數。

Copyright © Linux教程網 All Rights Reserved