2016-10-20 21 views
7

निम्नलिखित प्रोग्राम में मैंने pthread_t थ्रेड 1 बनाया जो फ़ंक्शन func() में क्रैश हुआ। मुझे कमांड main() में वास्तव में क्या हुआ, इसमें दिलचस्पी है।क्या होता है जब बच्चे थ्रेड क्रैश और मुख्य प्रतीक्षा में शामिल होने के लिए?

मैं प्रोग्राम के नीचे भाग गया और "पूर्ण" प्रिंट करके सामान्य रूप से बाहर निकल गया। मुझे नहीं पता क्यों?

#include <iostream> 
#include <string> 
#include <vector> 
#include <map> 
#include <cstring> 
#include <climits> 
#include <cstdio> 
#include<pthread.h> 
#include <stdlib.h> 
using namespace std; 

void* func(void *data) 
{ 
    cout<<"Calling func"<<(long)(data)<<endl; 
    int *a; 
    cout<<a[2]<<endl; 
    pthread_exit(0); 
} 

int main() 
{ 
    pthread_t thread1; 
    pthread_create(&thread1, 0 , &func, (void*)2); 
    pthread_join(thread1, NULL); 
    cout<<"complete"<<endl; 

} 
+0

आपने अपरिभाषित व्यवहार का आह्वान किया। आप भाग्यशाली थे (कार्यक्रम) कार्यक्रम जारी रहा और ऐसा लगता है जैसे सभी ब्रह्मांड में सही थे। इस प्रकार यूबी की प्रकृति। – WhozCraig

+0

@WhozCraig वहां कौन सा हिस्सा "अपरिभाषित" है? – GhostCat

+1

@GostCat एक अनिश्चित सूचक को संदर्भित करता है, एक के लिए। – WhozCraig

उत्तर

2

धागे अधिकतर स्वतंत्र होते हैं, जिसका अर्थ यह है कि प्रत्येक थ्रेड सिग्नल-हैंडलर का उपयोग "क्रैश"-सिग्नल को पकड़ने के लिए कर सकता है, बिना अन्य धागे भी मारे जा सकते हैं। सिग्नल हैंडलर को जोड़ने की जरूरत है।

स्रोत: संकेत मैनपेज http://man7.org/linux/man-pages/man7/signal.7.html

एक संकेत के रूप में एक प्रक्रिया के लिए उत्पन्न किया जा सकता है (और इस प्रकार लंबित) एक पूरी (जैसे, जब मार का उपयोग करके भेजा (2)) या एक विशिष्ट थ्रेड के लिए (जैसे, इस तरह के SIGSEGV और SIGFPE रूप खास संकेतों, एक विशिष्ट मशीन-भाषा अनुदेश को क्रियान्वित करने का एक परिणाम के रूप में उत्पन्न के रूप में pthread_kill का उपयोग कर एक विशिष्ट थ्रेड पर लक्षित संकेत कर रहे हैं, धागा निर्देशित कर रहे हैं (3))। एक प्रक्रिया निर्देशित सिग्नल किसी भी को उन थ्रेडों में से एक को वितरित किया जा सकता है, जिनमें वर्तमान में सिग्नल अवरुद्ध नहीं है। यदि किसी एक से अधिक धागे में सिग्नल अनब्लॉक किया गया है, तो कर्नेल सिग्नल वितरित करने के लिए एक मनमाना धागा चुनता है।

+1

जोड़ा है जो केवल तब लागू होता है जब 'SIGSEGV' में एक हैंडलर स्थापित होता है, जिस स्थिति में थ्रेड "क्रैश" नहीं होता - यह सिग्नल हैंडलर में प्रवेश करता है। अगर थ्रेड वास्तव में दुर्घटनाग्रस्त हो गया (कोई सिग्नल हैंडलर स्थापित नहीं है) तो पूरी प्रक्रिया मारे जायेगी। – caf

5

प्रक्रिया आपके मामले में ही सीमित हो जाएगी।

यदि आप a पर न्यूल को असाइन करना चाहते हैं तो आप देख सकते हैं कि यह सभी संभावनाओं में दुर्घटनाग्रस्त हो जाएगा। वर्तमान कोड में आप गैर-निर्धारित तरीके से a का आह्वान करते हैं। कुछ यादृच्छिक स्थान का संदर्भ a द्वारा किया जाता है। इसलिए व्यवहार अपरिभाषित है। कभी-कभी आपको main में लॉग स्टेटमेंट दिखाई देगा, अन्य बार प्रोग्राम क्रैश हो जाएगा। इस तरह के निष्पादन पर प्रोग्राम क्रैश होने पर अपने आप को भाग्यशाली मानें

यदि थ्रेड एक पूर्ण सूचक डी-संदर्भ करता है, तो यह पूरी प्रक्रिया को नीचे ले जाएगा। यह एक प्रक्रिया दुर्घटनाग्रस्त है और धागा दुर्घटना नहीं है।

+0

"यदि आप एक को असाइन करना चाहते थे तो आप देख सकते हैं कि यह निश्चित रूप से दुर्घटनाग्रस्त हो जाएगा" नहीं, निश्चित रूप से नहीं। यह अभी भी अपरिभाषित व्यवहार है। – juanchopanza

+0

@jaunchopanza, सहमत हैं। नल-पॉइंटर डिफरेंस के साथ प्रक्रिया क्रैश की संभावना बहुत अधिक गैर-शून्य भेदभाव है। मैं तदनुसार जवाब संपादित करूंगा। – Prabhu

+0

@ प्रभु हां, संपूर्ण कार्यक्रम नल डी-रेफरेंसिंग के मामले में क्रैश हो रहा है, इसलिए यदि कोई थ्रेड दुर्घटनाग्रस्त हो जाता है तो पूरी प्रक्रिया पागल हो जाती है। सही? – EmptyData

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