2010-02-05 17 views
5

मैं एक माइक्रोकंट्रोलर के सिमुलेशन को लागू करने की कोशिश कर रहा हूं। यह अनुकरण एक घड़ी चक्र को एक विशिष्ट माइक्रोकंट्रोलर के सटीक प्रतिनिधित्व करने के लिए नहीं है बल्कि कोड की सामान्य शुद्धता की जांच करें।मैं एक और थ्रेड कैसे निलंबित करूं (वर्तमान में नहीं)?

मैंने सामान्य कोड निष्पादित करने वाला एक "मुख्य धागा" और आईएसआर कोड निष्पादित करने वाला दूसरा थ्रेड होने का विचार किया। जब भी एक आईएसआर चलाने की जरूरत है, आईएसआर धागा "मुख्य धागा" निलंबित करता है।

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

एक पीओआर (रीसेट पर पावर) को न केवल निलंबित करके मुख्य थ्रेड (और पीओआर फ़ंक्शन निष्पादित करने वाला नया शुरू करने) को लागू किया जा सकता है।

विंडोज एपीआई आवश्यक कार्यों को प्रदान करता है। लेकिन उपरोक्त पॉज़िक्स धागे (लिनक्स पर) के साथ ऐसा करना असंभव प्रतीत होता है।

मैं वास्तविक हार्डवेयर स्वतंत्र माइक्रोकंट्रोलर कोड को बदलना नहीं चाहता हूं। इसलिए लंबित इंटरप्ट्स की जांच के लिए कुछ भी डालना एक विकल्प नहीं है।

गैर अच्छी तरह से व्यवहार किए गए बिंदुओं पर इंटरप्ट प्राप्त करना वांछनीय है, क्योंकि यह माइक्रोकंट्रोलर पर भी होता है (जब तक आप इंटरप्ट को अवरुद्ध नहीं करते)।

क्या लिनक्स पर एक और धागा निलंबित करने का कोई तरीका है? (डिबगर्स को किसी भी तरह उस विकल्प का उपयोग करना चाहिए, मुझे लगता है।)

कृपया, मुझे मत बताओ यह एक बुरा विचार है। मुझे पता है कि ज्यादातर परिस्थितियों में यह सच है। लेकिन मुख्य कोड मानक libs या लॉक/mutexes/semaphores का उपयोग नहीं करता है।

+0

ओह प्रिय। अन्य धागे को मारना एक बहुत ही खतरनाक व्यवसाय है, जो आपके कार्यक्रम में किसी भी ताले या अन्य संसाधनों को स्थायी रूप से खराब कर सकता है। मनमानी बिंदुओं पर एक और धागा निलंबित करना उतना बुरा नहीं है, लेकिन फिर भी ... – ephemient

+0

मुख्य थ्रेड कोड किसी भी ताले का उपयोग नहीं करेगा (एक वर्णित है जिसे इसे निलंबित या मारने से रोकता है) या गतिशील संसाधन आवंटित करता है। यह मानक पुस्तकालयों का उपयोग नहीं करता है। –

+0

यह ग्लिब मेलिंग सूची [यहां] (http: //sources.redhat पर भी पूछा गया था।कॉम/एमएल/libc-help/2010-05/msg00014.html)। हालांकि, बिना किसी परिणाम के। – Albert

उत्तर

3

किसी भी तरह से मुझे लगता है कि अन्य थ्रेड सिगस्टॉप काम भेज रहा है।

हालांकि, आप सेनेओगियर्स.म्यूटेक्स और वैश्विक चर शामिल कुछ थ्रेड संचार लिखने से कहीं बेहतर हैं।

यदि आप अन्य थ्रेड को malloc() में निलंबित करते हैं, तो आप देखते हैं और आप malloc() -> deadlock को कॉल करते हैं।

क्या मैंने उल्लेख किया है कि सी मानक लाइब्रेरी फ़ंक्शंस के बहुत सारे, आपके द्वारा उपयोग की जाने वाली अन्य पुस्तकालयों को अकेले छोड़ दें, आपकी पीठ के पीछे मॉलोक() को कॉल करेंगे?

संपादित करें:

हम्म, कोई मानक लाइब्रेरी कोड नहीं। हो सकता है कि सिग्नल हैंडलर से setjmp/longjump() को पीओआर अनुकरण करने के लिए और एक सिग्नल हैंडियर को बाधा अनुकरण करने के लिए उपयोग करें।

जो इसे कम करते हैं: उत्तर EDIT के बाद सामग्री के लिए स्वीकार किया गया था, जो एक विशिष्ट परिदृश्य है जिसे किसी अन्य परिदृश्य में उपयोग नहीं किया जा सकता है।

+0

वैसे, सिद्धांत रूप में पुन: प्रवेश स्मृति आवंटक मौजूद हैं, और आपका libc डिफ़ॉल्ट रूप से एक का उपयोग भी कर सकता है। लेकिन हाँ, ओपी का अनुरोध बहुत खतरनाक है। – ephemient

+0

मैं किसी भी मानक पुस्तकालय का उपयोग करने का इरादा नहीं रखता हूं। अनुकरण करने के लिए कोड एक पूर्ण मिनी-ओएस है जो सी मानक पुस्तकालयों पर आधारित नहीं है। –

+0

जहां तक ​​मुझे लिनक्स (कर्नेल 2.6) पर पता है, सिग्स्टॉप को एक थ्रेड पर भेजना संभव नहीं है। इसके बजाय एक प्रक्रिया के सभी धागे बंद कर दिए गए हैं। वह मेरी समस्या का समाधान नहीं करेगा। –

1

सोलारिस में thr_suspend (3C) कॉल है जो आप चाहते हैं जो करेंगे। सोलारिस को एक संभावना पर स्विच कर रहा है?

इसके अलावा, आपको शायद म्यूटेक्स और/या सेमफोर के साथ कुछ जिमनास्टिक करना होगा। समस्या यह है कि जब आप mutex को चेक करते हैं तो आप केवल निलंबित कर देंगे, जो शायद एक अच्छी तरह से व्यवहार बिंदु पर होगा। जो वास्तव में आप पूरा करने की कोशिश कर रहे हैं उसके आधार पर, यह अब वांछनीय हो सकता है।

+0

मैं घर पर उबंटू का उपयोग करता हूं। अगर मुझे एक अलग ओएस पर स्विच करना है, तो मैं विंडोज़ पर भी स्विच कर सकता हूं। लेकिन संकेत के लिए धन्यवाद। म्यूटेक्स और सेमफोर केवल वर्तमान धागे को प्रभावित करते हैं। और मैं सिमुलेशन के लिए उपकरण कोड डालना नहीं चाहता हूं। –

1

यह मुख्य धागा आईएसआर निष्पादित करने के लिए अधिक समझ में आता है - क्योंकि असली नियंत्रक काम करता है (संभवतः)। यदि प्रत्येक बाधा लंबित है, तो प्रत्येक अनुरूपित निर्देश के बाद बस जांच करें, और इंटरप्ट वर्तमान में सक्षम हैं - यदि हां, तो आईएसआर को कॉल अनुकरण करें।

दूसरा धागा अभी भी उपयोग किया जाता है - लेकिन यह केवल उन स्थितियों के लिए सुनता है जो बाधा उत्पन्न करते हैं, और प्रासंगिक अवरोध लंबित के रूप में चिह्नित करते हैं (अन्य धागे को बाद में लेने के लिए)।

+0

बेशक, मैंने अलग "संचार धागे" रखने का विचार किया लेकिन वे सामान्य प्रक्रिया के लिए महत्वपूर्ण नहीं हैं। मुझे कोड में कोई उपकरण नहीं चाहिए जो इंटरप्ट्स की जांच करता है। मेरे पास माइक्रोकंट्रोलर पर भी नहीं है। मैं एक विशिष्ट माइक्रोकंट्रोलर को अनुकरण नहीं करना चाहता हूं। तो microcontroller के नकली निर्देश के रूप में ऐसी कोई बात नहीं है। –

+0

वैसे, यह मेरे प्रश्न का कोई जवाब नहीं है। –

5

हॉटस्पॉट जावा वीएम लिनक्स पर जावा थ्रेड के लिए निलंबन/फिर से शुरू करने के लिए SIGUSR2 का उपयोग करता है।

SIGUSR2 के लिए एक संकेत हैंडलर के आधार पर एक प्रक्रिया है हो सकता है:

SIGUSR2 के लिए एक संकेत हैंडलर प्रदान करना एक धागा एक ताला (जो पहले से ही संकेत भेजने धागा ने अधिग्रहण कर लिया गया है) अनुरोध करने के लिए अनुमति देता है।

यह धागा को निलंबित करता है।

जैसे ही निलंबित थ्रेड लॉक जारी करता है, सिग्नल हैंडलर (और होगा?) लॉक प्राप्त कर सकता है। सिग्नल हैंडलर तुरंत लॉक जारी करता है और सिग्नल हैंडलर छोड़ देता है।

यह धागा फिर से शुरू करता है।

आईएसआर की वास्तविक प्रसंस्करण शुरू करने से पहले मुख्य थ्रेड सिग्नल हैंडलर में यह सुनिश्चित करने के लिए एक नियंत्रण चर लागू करना आवश्यक होगा। (विवरण इस बात पर निर्भर करता है कि सिग्नल हैंडलर को सिंक्रनाइज़ या असीमित रूप से कहा जाता है।)

मुझे नहीं पता, अगर यह जावा वीएम में बिल्कुल किया गया है, लेकिन मुझे लगता है कि उपरोक्त प्रक्रिया मुझे जो चाहिए ।

9

सिगस्टॉप काम नहीं करता है - यह हमेशा पूरी प्रक्रिया को रोक देता है। इसके बजाय आप कुछ अन्य संकेतों का उपयोग कर सकते हैं, निलंबित और शुरू करने के लिए SIGUSR2 के लिए SIGUSR1 कहते हैं:

// at process start call init_pthread_suspending to install the handlers 
// to suspend a thread use pthread_kill(thread_id, SUSPEND_SIG) 
// to resume a thread use pthread_kill(thread_id, RESUME_SIG) 

#include <signal.h> 

#define RESUME_SIG SIGUSR2 
#define SUSPEND_SIG SIGUSR1 

static sigset_t wait_mask; 
static __thread int suspended; // per-thread flag 

void resume_handler(int sig) 
{ 
    suspended = 0; 
} 

void suspend_handler(int sig) 
{ 
    if (suspended) return; 
    suspended = 1; 
    do sigsuspend(&wait_mask); while (suspended); 
} 

void init_pthread_suspending() 
{ 
    struct sigaction sa; 

    sigfillset(&wait_mask); 
    sigdelset(&wait_mask, SUSPEND_SIG) 
    sigdelset(&wait_mask, RESUME_SIG); 

    sigfillset(&sa.sa_mask); 
    sa.sa_flags = 0; 
    sa.sa_handler = resume_handler; 
    sigaction(RESUME_SIG, &sa, NULL); 

    sa.sa_handler = suspend_handler; 
    sigaction(SUSPEND_SIG, &sa, NULL); 
} 

मैं की तरह "आप एक और धागा को निलंबित नहीं करना चाहिए, कि बुरा है" उत्तर से बहुत नाराज़ हूँ। दोस्तों आप क्यों मानते हैं कि दूसरों बेवकूफ हैं और वे नहीं जानते कि वे क्या कर रहे हैं? कल्पना कीजिए कि दूसरों ने भी डेडलॉकिंग के बारे में सुना है और अभी भी पूरी चेतना में, अन्य धागे को निलंबित करना चाहते हैं। यदि आपके पास उनके प्रश्न का वास्तविक उत्तर नहीं है तो आप अपने और पाठकों के समय को बर्बाद क्यों करते हैं।

एक हां, आईएमओ pthreads बहुत कम दृष्टि वाले एपीआई, POSIX के लिए एक अपमान है।

+0

मैं इसे एक सी ++ संदर्भ में उपयोग करना चाहता हूं, एक अपवाद इंजेक्शन करके थ्रेड को बाधित करना, आरएआईआई वस्तुओं की सफाई करना। मैं विंडोज से बंदरगाह की कोशिश कर रहा हूं, जहां मैं समस्या थ्रेड को निलंबित करता हूं और फिर से शुरू करने से पहले एक अपवाद फेंक की शुरुआत में निर्देश सूचक को संशोधित करता हूं। यह अच्छी तरह से काम करता है, और अधिकांश समय मैं उपप्रणाली को पुनरारंभ करने के बाद पुनर्प्राप्त कर सकता हूं, भले ही वे अनंत लूप में प्रवेश करते हैं, साझा स्थिति के न्यूनतम मैन्युअल क्लीनअप (जैसे म्यूटेक्स रीसेट करना)। मैं अपने लिनक्स संस्करण की क्षमता को कैसे पोर्ट करूं? हैंडलर स्टैक फ्रेम के कारण हैंडलर से फेंकने से बचने के लिए मुझे लगता है कि अधिकांश लेख। –

0

pthread_kill (3) और SIGUSR1, SIGUSER2 सिग्नल का उपयोग करने वाला समाधान एक अच्छा समाधान है लेकिन अभी भी समवर्ती समस्या का कारण बन सकता है। क्या एक सुरक्षित बिंदु पर सभी धागे (मुख्य धागे को छोड़कर) को निलंबित करने का कोई तरीका है यानी निलंबन धागे के समय किसी भी लॉक को अधिग्रहण नहीं करना चाहिए था या सिस्टम कॉल में नहीं चलना चाहिए था?

+0

क्या यह एक उपयुक्त उत्तर है। यह मेरे अंत में एक प्रश्न की तरह लगता है। कृपया संपादित करें और स्पष्ट हो – Freakyuser

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