歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> POSIX線程清理函數

POSIX線程清理函數

日期:2017/3/1 11:17:59   编辑:Linux編程

POSIX清理函數的調用時機:

調用pthread_exit()時,會調用清理函數;通過return返回的線程不會調用。

被別的線程取消的時候,會調用。

pthread_cleanup_pop()參數為非零時,會調用。

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <windows.h> // Sleep
  4. pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
  5. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  6. struct Node
  7. {
  8. int number;
  9. struct Node *next;
  10. } *head = NULL;
  11. // 清理函數
  12. void cleanup_handler(void *node)
  13. {
  14. printf("Cleanup handler of second thread.\n");
  15. free(node);
  16. pthread_mutex_unlock(&mtx);
  17. }
  18. void* thread_func(void *arg)
  19. {
  20. struct Node *p = NULL;
  21. // 清理函數入棧,此demo只需一個清理函數
  22. pthread_cleanup_push(cleanup_handler, p);
  23. while (true)
  24. {
  25. pthread_mutex_lock(&mtx);
  26. if (head == NULL)
  27. {
  28. pthread_cond_wait(&cond, &mtx);
  29. }
  30. p = head;
  31. head = head->next;
  32. printf("Got %d from front of queue\n", p->number);
  33. free(p);
  34. pthread_mutex_unlock(&mtx);
  35. }
  36. /* 若從此處終止線程,則屬於正常退出,無需清理。所以,只需將清理函數出棧。故而用
  37. 參數零。若是從上面的“取消點”退出,則清理函數出棧時被調用:鎖被打開,同時釋放資源。*/
  38. pthread_cleanup_pop(0);
  39. return 0;
  40. }
  41. int main(int argc, char* argv[])
  42. {
  43. pthread_t tid;
  44. pthread_create(&tid, NULL, thread_func, NULL);
  45. for (int i = 0; i < 10; i++)
  46. {
  47. struct Node* p = (Node *)malloc(sizeof(struct Node));
  48. p->number = i;
  49. // <!-- 對head操作屬於臨界區
  50. pthread_mutex_lock(&mtx);
  51. p->next = head;
  52. head = p;
  53. pthread_cond_signal(&cond);
  54. pthread_mutex_unlock(&mtx);
  55. // 所以要用互斥鎖保護起來--!>
  56. Sleep(1);
  57. }
  58. printf("Main thread wants to cancel the 2nd thread.\n");
  59. /* 關於pthread_cancel,有一點額外的說明,它是從外部終止子線程,子線程會在
  60. 最近的取消點,退出線程。而在我們的代碼裡,最近的取消點是pthread_cond_wait()了。*/
  61. pthread_cancel(tid);
  62. pthread_join(tid, NULL);
  63. printf("All done -- exiting\n");
  64. return 0;
  65. }
Copyright © Linux教程網 All Rights Reserved