2009-03-19 11 views
6

मुझे एक अजीब समस्या है। हर पंक्ति से पहलेpthread_cond_timedwait तुरंत लौट रहा है

dbg("condwait: timeout = %d, %d\n", 
     abs_timeout->tv_sec, abs_timeout->tv_nsec); 
    ret = pthread_cond_timedwait(&q->q_cond, &q->q_mtx, abs_timeout); 
    if (ret == ETIMEDOUT) 
    { 
     dbg("cond timed out\n"); 
     return -ETIMEDOUT; 
    } 

dbg कॉल gettimeofday और समय के साथ लाइन पहले जोड़ता: मैं निम्नलिखित कोड है। यह निम्न उत्पादन में परिणाम है:

7.991151: condwait: timeout = 5, 705032704 
    7.991158: cond timed out 

आप देख सकते हैं, केवल 7 दो डिबग लाइनों के बीच में पारित माइक्रोसेकंड, अभी तक pthread_cond_timedwait लौटे ETIMEDOUT। ये केसे हो सकता हे?

int ret; 
ret = pthread_condattr_init(&attributes); 
if (ret != 0) printf("CONDATTR INIT FAILED: %d\n", ret); 
ret = pthread_condattr_setclock(&attributes, CLOCK_REALTIME); 
if (ret != 0) printf("SETCLOCK FAILED: %d\n", ret); 
ret = pthread_cond_init(&q->q_cond, &attributes); 
if (ret != 0) printf("COND INIT FAILED: %d\n", ret); 

(त्रुटि संदेशों में से कोई भी बाहर मुद्रित कर रहे हैं): मैं भी जब cond चर आरंभ कुछ और करने के लिए घड़ी की स्थापना की कोशिश की। मैंने CLOCK_REALTIME और CLOCK_MONOTONIC दोनों की कोशिश की।

यह कोड अवरुद्ध कतार का हिस्सा है। मुझे कार्यक्षमता की आवश्यकता है कि यदि 5 सेकंड में इस कतार पर कुछ भी नहीं लगाया जाता है, तो कुछ और होता है। म्यूटेक्स और कंड दोनों प्रारंभिक होते हैं, क्योंकि ब्लॉकिंग कतार ठीक काम करती है अगर मैं pthread_cond_timedwait का उपयोग नहीं करता हूं।

उत्तर

14

pthread_cond_timedwait एक पूर्ण समय लेता है, न कि एक सापेक्ष समय। आपको अपने टाइमआउट मान पर वर्तमान समय में जोड़कर अपना प्रतीक्षा समय पूर्ण करना होगा।

+0

ओह मिला। पेट का समय क्या है यह जानने के लिए आप pthread_get_expiration_np() का उपयोग कर सकते हैं। – Claudiu

+3

@Claudiu pthread_get_expiration_np() मेरे जीएनयू/लिनक्स पर उपलब्ध नहीं है। इसके बजाय मुझे यह करना था: 'समय अब; gettimeofday (और अब, NULL); लंबे int abstime_ns_large = now.tv_usec * 1000 + delay_ns; timespec abstime = {now.tv_sec + (abstime_ns_large/1000000000), abstime_ns_large% 1000000000}; 'जहां देरी_एनएस नैनोसेकंड में वांछित देरी है।फिर अपने pthread_cond_timedwait कॉल में abstime का उपयोग करें। –

3

हालत परिवर्तक उग्र रूप से अनब्लॉक कर सकता है। आपको इसे लूप में जांचना होगा और प्रत्येक बार स्थिति की जांच करनी होगी। आपको शायद टाइमआउट मान भी अपडेट करना होगा।

मुझे pthread_cond_timedwaithere के लिए कुछ दस्तावेज मिला।

हालत चरों का उपयोग करते वहाँ हमेशा एक बूलियन विधेय साझा प्रत्येक शर्त के साथ जुड़े चर शामिल इंतजार यह सच है अगर धागा आगे बढ़ना चाहिए है। से pupread_cond_timedwait() या pthread_cond_wait() फ़ंक्शन हो सकता है। चूंकि से वापसी के बाद pthread_cond_timedwait() या pthread_cond_wait() इस के मूल्य के बारे में कुछ भी इंगित नहीं करता है, तो अनुमान इस तरह के रिटर्न पर फिर से मूल्यांकन किया जाना चाहिए।

7

timespec में ओवरफ़्लो आमतौर पर अजीब टाइमआउट के लिए अपराधी होता है। EINVAL के लिए
की जांच:

void timespec_add(struct timespec* a, struct timespec* b, struct timespec* out) 
{ 
    time_t sec = a->tv_sec + b->tv_sec; 
    long nsec = a->tv_nsec + b->tv_nsec; 

    sec += nsec/1000000000L; 
    nsec = nsec % 1000000000L; 

    out->tv_sec = sec; 
    out->tv_nsec = nsec; 
} 
0

जैसा कि पहले ही अन्य उत्तर में उल्लेख किया है आप पूर्ण समय का उपयोग करने के लिए है। सी 11 के बाद से आप timespec_get() का उपयोग कर सकते हैं।

struct timespec time; 
timespec_get(&time, TIME_UTC); 
time.tv_sec += 5; 

pthread_cond_timedwait(&cond, &mutex, &time); 
संबंधित मुद्दे