[英]How to call manually fork handlers registered by `pthread_atfork()`?
我在 glibc 中使用vfork()
並根據vfork()
的手冊頁:
當使用 NPTL 線程庫的多線程程序調用 vfork() 時,不會調用使用 pthread_atfork(3) 建立的分叉處理程序。 在這種情況下,在使用 LinuxThreads 線程庫的程序中調用分叉處理程序。
在 NPTL 上,不會調用分叉處理程序。 在我的具體情況下,我需要這種保護,以便調用 fork 處理程序的方式與調用fork()
時的方式相同。
有沒有辦法讓 pthread 庫調用注冊的處理程序,甚至手動調用它們?
我想到了使用clone()
因為它可以更精確地控制克隆過程,但它也避免了 fork 處理程序:
使用 pthread_atfork(3) 注冊的處理程序不會在克隆調用期間執行。
另請閱讀如何重置由 pthread_atfork 注冊的處理程序——在我的例子中,我不想刪除處理程序,而只想調用它們。
謝謝。
有沒有辦法讓 pthread 庫調用注冊的處理程序,甚至手動調用它們?
如果你成功地做到了這一點,你的程序就會損壞。 沒有在vfork
上調用pthread_atfork
處理程序是有原因的。
atfork
處理程序的典型用法是保證父進程中持有的任何鎖在fork
之后在子進程和父進程中保持一致的 state。
沒有處理程序,假設線程T1
持有鎖L
,線程T2
調用fork
。 由於只有T2
會被復制到孩子中,因此L
將永遠保持鎖定狀態。 如果T2
需要那個鎖(假設它是malloc
鎖), T2
將死鎖( T1
在孩子中不存在)。
解決方案: pthread_atfork
處理程序。 在父進程中prepare()
將獲取L
,並且parent()
和child()
處理程序將分別在父進程和子進程中解鎖它們自己的L
實例。 一切都是快樂的1 。
現在考慮如果你在vfork
之后做同樣的事情會發生什么。 prepare()
按預期獲取L
,但是當您調用parent()
和child()
時,它們會解鎖L
的同一個實例(因為父進程和子進程共享內存)。 因此L
被解鎖了兩次,破壞了它!
1實際上,在多線程程序中調用fork
或vfork
充滿了危險,在存在任意庫的情況下安全地執行此操作幾乎是不可能的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.