2011-09-11 15 views
5

मैंने लिनक्स futex सिस्कल (FUTEX_WAIT ऑपरेशन) के साथ किसी समस्या में भाग लिया है कभी-कभी कारण के बिना प्रतीत होता है। प्रलेखन कुछ स्थितियों को निर्दिष्ट करता है जो इसे जल्दी वापस लौटा सकते हैं (FUTEX_WAKE के बिना) लेकिन इन सभी में गैर-शून्य रिटर्न मान शामिल हैं: EAGAIN यदि फ़्यूटेक्स पते पर मान मेल नहीं खाता है, तो ETIMEDOUT समय के लिए उस टाइमआउट, EINTR द्वारा बाधित होने पर प्रतीक्षा करता है एक (गैर-पुनरारंभ) सिग्नल इत्यादि। लेकिन मुझे 0 का रिटर्न वैल्यू दिखाई दे रहा है। FUTEX_WAKE के अलावा या set_tid_address पॉइंटर पॉइंट्स को फ्यूटेक्स को इंगित करने के लिए FUTEX_WAIT का रिटर्न वैल्यू 0?लिनक्स futex syscall नकली मूल्य 0 के साथ नकली wakes?

मामले में यह उपयोगी है, विशेष रूप से futex मैं पर इंतज़ार कर रहा था धागा टीआईडी ​​पता (CLONE_CHILD_CLEARTID साथ clone syscall द्वारा निर्धारित), और धागा समाप्त नहीं किया था। मेरा (जाहिरा तौर पर गलत) धारणा है कि FUTEX_WAIT ऑपरेशन रिटर्निंग 0 केवल तभी हो सकता है जब थ्रेड समाप्त हो गया हो, प्रोग्राम लॉजिक में गंभीर त्रुटियों का कारण बनता है, जिसे मैंने लूपिंग द्वारा तय किया है और फिर भी 0 लौटाए जाने पर भी पुनः प्रयास कर रहा है, लेकिन अब मैं उत्सुक हूं ऐसा क्यों हुआ।

#define _GNU_SOURCE 
#include <sched.h> 
#include <sys/syscall.h> 
#include <unistd.h> 
#include <linux/futex.h> 
#include <signal.h> 

static char stack[32768]; 
static int tid; 

static int foo(void *p) 
{ 
     syscall(SYS_getpid); 
     syscall(SYS_getpid); 
     syscall(SYS_exit, 0); 
} 

int main() 
{ 
     int pid = getpid(); 
     for (;;) { 
       int x = clone(foo, stack+sizeof stack, 
         CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND 
         |CLONE_THREAD|CLONE_SYSVSEM //|CLONE_SETTLS 
         |CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID 
         |CLONE_DETACHED, 
         0, &tid, 0, &tid); 
       syscall(SYS_futex, &tid, FUTEX_WAIT, x, 0); 
       /* Should fail... */ 
       syscall(SYS_tgkill, pid, tid, SIGKILL); 
     } 
} 

यह थोड़ी देर के लिए चलाने के लिए, पर यह अंततः Killed (SIGKILL) के साथ समाप्त करना चाहिए, जो केवल तभी संभव है धागा अभी भी जब FUTEX_WAIT रिटर्न मौजूद हैं:

यहाँ एक न्यूनतम परीक्षण का मामला है।

कोई भी यह मानने से पहले कि यह थ्रेड को नष्ट करने से पहले कर्नेल को फ्यूटेक्स को जगा रहा है (जो वास्तव में यहां मेरे न्यूनतम परीक्षण मामले में हो रहा है), कृपया ध्यान दें कि मेरे मूल कोड में, मैंने वास्तव में उपयोगकर्ता स्पेस कोड देखा FUTEX_WAIT लौटने के बाद अच्छी तरह से धागे में चल रहा है।

+0

मुझे लगता है कि हमें एक न्यूनतम उदाहरण देखने की आवश्यकता हो सकती है; काफी सलाह के साथ आना मुश्किल है, क्योंकि बहुत कुछ अज्ञात है (मैं अपने एक हंच को एक अस्थायी उत्तर के रूप में पोस्ट करूंगा, क्योंकि यह किसी टिप्पणी के लिए बड़ा है) – sehe

+0

दरअसल, मैं देखूंगा कि मैं न्यूनतम से एक साथ रख सकता हूं या नहीं उदाहरण। –

+0

एचएम, मुझे लगता है कि मैन पेज काफी अस्पष्ट है। 'FUTEX_WAIT' के रिटर्न वैल्यू के तहत स्थितियां गैर शून्य शर्तों को * त्रुटि * शर्तों के रूप में योग्य करती हैं, न केवल डायग्नोस्टिक्स। फिर बाद में यह कहता है "एक त्रुटि की स्थिति में, सभी ऑपरेशन 1 लौटाते हैं, और त्रुटि को इंगित करने के लिए इरनो सेट करते हैं।" दूसरी तरफ यहां स्थितियां ** त्रुटियों ** अनुभाग में दोहराई नहीं गई हैं। –

उत्तर

0

क्या आप माता-पिता या शिशु परिचालन पहले पूरा करने के बीच दौड़ की स्थिति से निपट सकते हैं? आप संभवतः इस सिद्धांत की जांच कर सकते हैं कि आपके foo() या क्लोन() के तुरंत बाद छोटी नींद डालने के लिए यह निर्धारित करने के लिए कि घटनाओं का एक मजबूर अनुक्रम समस्या को हल करता है या नहीं। मैं इस तरह से कुछ भी ठीक करने की सिफारिश नहीं करता, लेकिन यह जांच करने में मददगार हो सकता है। हो सकता है कि फ्यूटेक्स तब तक इंतजार न करने के लिए तैयार न हो जब तक बच्चे अपने प्रारंभिकरण के माध्यम से आगे नहीं निकलता है, लेकिन माता-पिता के क्लोन में कॉलर पर वापस जाने के लिए पर्याप्त है?

विशेष रूप से, CLONE_VFORK विकल्प की उपस्थिति का अर्थ यह है कि यह एक खतरनाक परिदृश्य है। आपको एक द्वि-दिशात्मक सिग्नलिंग तंत्र की आवश्यकता हो सकती है जैसे कि बच्चे माता-पिता को संकेत देता है कि यह इतना दूर हो गया है कि बच्चे के लिए इंतजार करना सुरक्षित है।

+0

यदि 'FUTEX_WAIT' कहलाता है तो 'tid' पहले से ही बोली मूल्य के साथ नहीं लिखा गया था, तो ऑपरेशन 0 के बजाय' EAGAIN' के साथ वापस आ जाएगा (वैसे भी, 'CLONE_PARENT_SETTID' ध्वज' का पूरा बिंदु 'क्लोन' पर है यह सुनिश्चित करना है कि धागा निष्पादित करने में सक्षम होने से पहले मान लिखा गया है।) मुझे उपयोगकर्ता स्पेस में दौड़ के लिए कोई संभावना नहीं दिख रही है क्योंकि कुछ भी नहीं दिलचस्प जगह उपयोगकर्ताओं में हो रहा है ... –

संबंधित मुद्दे