2010-08-24 19 views
12

जब मैं को main से कॉल करता हूं, तो प्रोग्राम कभी समाप्त नहीं होता है। मुझे कार्यक्रम खत्म होने की उम्मीद थी, क्योंकि मैं प्रोग्राम के एकमात्र धागे से बाहर निकल रहा था, लेकिन यह काम नहीं करता है। ऐसा लगता है लटका हुआ है।क्या मुख्य से pthread_exit को कॉल करना ठीक है?

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

int main(int argc, char *argv[]) 
{ 
    printf("-one-\n"); 

    pthread_exit(NULL); 

    printf("-two-\n"); 
} 

प्रोसेस एक्सप्लोरर पता चलता है कि (केवल) धागा Wait:DelayExecution स्थिति में है।

pthread_exit प्रलेखन के अनुसार:

प्रक्रिया एक निकास पिछले धागा के बाद 0 की स्थिति के साथ बाहर निकलने जाएगा समाप्त कर दिया गया। व्यवहार होगा जैसे कार्यान्वयन निकास() को थ्रेड समाप्ति समय पर शून्य तर्क के साथ कहा जाता है।

मैं देव-सी ++ v4.9.9.2 और pthreads-Win32 v2.8.0.0 (libpthreadGC2.a रूप से लिंक हो) का उपयोग कर रहा हूँ।

लाइब्रेरी ठीक प्रतीत होती है (उदाहरण के लिए, pthread_self या pthread_createmain से ठीक काम करता है)।

क्या main से pthread_exit पर कॉल करने के लिए मुझे कोई कारण नहीं है?

+1

'pthread_exit (NULL) के बजाय आप' 0 वापस क्यों नहीं लौटते; '? –

+2

मुझे पता है कि मैं _could_ 'वापसी' या 'बाहर निकलें'। मैं सिर्फ यह जानना चाहता हूं कि 'pthread_exit' को कॉल करके मुख्य धागे को समाप्त करना कानूनी है या नहीं। – user429788

+0

मुख्य() से लौटना pthread_exit() चलाने के लिए बहुत अलग है। उत्तरार्द्ध शेष जीवित धागे को खत्म करने देगा और फिर वापसी मूल्य 0. से बाहर निकल जाएगा। पूर्व तुरंत सबकुछ समाप्त कर देगा। –

उत्तर

12

अच्छी तरह से यह निश्चित रूप से लिथक्स के लिनक्स कार्यान्वयन में कानूनी है, pthreads_exit में नोट्स अनुभाग देखें। इसमें कहा गया है

अन्य धागे निष्पादन जारी रखने के लिए अनुमति देने के लिए, मुख्य थ्रेड pthread_exit() के बजाय बाहर निकलें (3) की तुलना में फोन करके समाप्त करना चाहिए।

इसके अलावा, स्रोत कोड here (अंत torwads) पर एक नज़र से पता चलता है कि यह मोटे तौर पर _endthread या _endthreadex करने के लिए अनुवाद। उन लोगों के लिए प्रलेखन here प्रारंभिक धागे में कॉल न करने का कोई उल्लेख नहीं करता है।

+0

तब मुझे लगता है कि यह Win32 कार्यान्वयन (http://sourceware.org/pthreads-win32/bugs.html) में भी कानूनी होना चाहिए। मैं एक ज्ञात बग की तलाश में हूं जो इस व्यवहार को समझाता है, लेकिन मुझे यह नहीं मिला। मेरी राय में, या तो यह एक छोटी गाड़ी व्यवहार है या एक वास्तविक कारण है कि मुझे 'pthread_exit' को 'pthreads_win32' पर कॉल नहीं करना है। क्या कोई इन परिकल्पनाओं की पुष्टि कर सकता है? – user429788

+0

@matasierra: मैंने जवाब के जवाब में कुछ और विवरण जोड़ा है। इसके अलावा, वास्तव में मुख्य रूप से निष्पादन क्या है? – torak

+0

पहला 'printf' वास्तव में मुद्रित होता है, लेकिन दूसरा वाला (जैसा अपेक्षित नहीं है) है। समस्या यह है कि कार्यक्रम समाप्त नहीं होगा। यह बस _frozen_ की तरह हो जाता है। – user429788

12

यह पूरी तरह कानूनी और इरादा व्यवहार है। पूरी प्रक्रिया केवल तब समाप्त होती है जब सभी धागे समाप्त हो जाते हैं या exit को स्पष्ट रूप से या स्पष्ट रूप से कहा जाता है।

main से सामान्य वापसी exit पर कॉल के बराबर है। यदि आप mainpthread_exit के साथ समाप्त करते हैं तो आप स्पष्ट रूप से कह रहे हैं कि आप अन्य धागे जारी रखना चाहते हैं।

0

लिनक्स पर परीक्षण करते समय (सेंटोस लिनक्स रिलीज 7.2.1511 (कोर)) मैंने पाया कि वास्तव में मुख्य कार्यक्रम "बच्चे" थ्रेड जारी रखने की प्रतीक्षा करता है। इसके अलावा, मैं नहीं मुख्य से एक वापसी कोड बाहर पारित करने में सक्षम है, हालांकि यह pthread_exit (के लिए तर्क के रूप में निर्दिष्ट किया जा सकता) था, के रूप में राउल ने कहा कि इसके बाद के संस्करण यह हमेशा से बाहर निकलें कोड के साथ देता है 0:

retval=3; 
pthread_exit(&retval); 

हम यह भी एक मनाया क्लैंग कंपाइलर का उपयोग करते समय त्रुटि संदेश (संस्करण 3.4।2) और सैनिटाइज़र विकल्प:

==5811==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7f4c090321d0 in thread T0 
#0 0x7f4c08be3e29 in __interceptor_free (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x65e29) 
#1 0x7f4c08333358 in free_key_mem (/lib64/libdl.so.2+0x1358) 
#2 0x7f4c08745bc1 in __nptl_deallocate_tsd (/lib64/libpthread.so.0+0x7bc1) 
#3 0x7f4c07771b38 in __libc_start_main (/lib64/libc.so.6+0x21b38) 
#4 0x7f4c08bfa08c in _start (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x7c08c) 

AddressSanitizer can not describe address in more detail (wild memory access suspected). 
SUMMARY: AddressSanitizer: bad-free ??:0 __interceptor_free 
==5811==ABORTING 
संबंधित मुद्दे