2009-04-30 16 views
11

मैं विश्वविद्यालय के लिए एक अभ्यास कर रहा था जहां मुझे बाहर निकलने के साथ एक मूल्य वापस करना पड़ा, वह मूल्य वास्तव में कुछ की गिनती थी। यह 255 से ऊपर हो सकता है (जो बाहर निकलें() संभाल नहीं सकता है) लेकिन शिक्षक ने परीक्षण डेटा का उपयोग करने का सुझाव दिया जहां गिनती उस मूल्य से ऊपर कभी नहीं जा सकती थी।बाहर निकलने() स्थिति पर 256 तक सी ओवर डिवीजन में WEXITSTATUS मैक्रो का उपयोग करने में कोई लाभ?

इस सब के बाद, मुझे इस गिनती मूल्य को संभालने की आवश्यकता है, बाहर निकलने की स्थिति, मुझे यह मूल्य मुख्य प्रक्रिया में waitpid() का उपयोग कर मिला है। मेरे आश्चर्य की बात है कि, यदि बाल प्रक्रिया 1 लौटा दी गई, तो मुख्य प्रक्रिया में "असली" मान 256 था, 2 512 था और इसी तरह ...

मुझे इस मान को प्रिंट करने की आवश्यकता है इसलिए मैंने इसे 256 तक विभाजित किया और वह हो गया था। हालांकि, अगर मैं WEXITSTATUS() मैक्रो का उपयोग, मैं भी इस मूल्य तरह से मैं यह चाहता हूँ ...

मैं सी स्रोत कोड को देखा मिल जाएगा और यह है कि मैं क्या पता चला:

#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8) 

मैं समझता हूं कि यहां क्या हो रहा है, उदाहरण के लिए, बाइनरी में 512 10 0000 0000 है, दाईं ओर 8 ओ स्थानांतरित करने से 00 0000 0010, जो दशमलव में 2 है। मुझे इस मैक्रो में क्या समझ में नहीं आता है कि & ऑपरेटर और तथ्य यह है कि 0xff00 एक यादृच्छिक संख्या प्रतीत होता है (शायद यह नहीं है, यह कहां से आता है?)। यह वास्तव में क्या करता है, मैक्रो में "& 0xff00" क्यों है? क्या यह इसके साथ काम नहीं करेगा?

और इस विषय में असली सवाल, मेरे मैक्रो में 256 तक विभाजित करने के समान ही बात है?

उत्तर

16

और इस विषय में असली सवाल एक ही बात इस मैक्रो मेरी कोड में 256 से विभाजित के रूप में कॉल करने के लिए है?

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

waitpid() द्वारा संग्रहीत स्थिति दोनों कारणों को एन्कोड करता है कि बच्चे की प्रक्रिया समाप्त हो गई थी और निकास कोड। कारण कम से कम महत्वपूर्ण बाइट (status & 0xff द्वारा प्राप्त) में संग्रहीत किया जाता है, और निकास कोड अगले बाइट में संग्रहीत किया जाता है (status & 0xff00 द्वारा मुखौटा और WEXITSTATUS() द्वारा निकाला गया)। जब प्रक्रिया सामान्य रूप से समाप्त हो जाती है, तो कारण 0 है और WEXITSTATUS 8 से स्थानांतरित करने के बराबर है (या 256 तक विभाजित)। हालांकि, अगर सिग्नल (जैसे कि एसआईजीएसईजीवी) द्वारा प्रक्रिया को मार दिया जाता है, तो कोई एक्जिट कोड नहीं होता है, और आपको बाइट कारण से सिग्नल नंबर निकालने के लिए WTERMSIG का उपयोग करना होगा।

2

यहां 0xff00 एक बाइनरी मास्क (link text) है। एक मूल्य के साथ इसे सभी बिट्स शून्य पर सेट करता है, दूसरी बाइट को छोड़कर (दाएं से गिनती)।

आपको केवल उस प्रक्रिया पर WEXITSTATUS का उपयोग करना चाहिए जो सामान्य रूप से बाहर निकलने के लिए जाना जाता है। यह जानकारी WIFEXITED मैक्रो द्वारा दी गई है।

और इस विषय में असली प्रश्न, 256 तक विभाजित करने के रूप में मेरे कोड में इस मैक्रो को कॉल करने के लिए एक ही बात है?

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

3

यदि स्थिति चर एक मशीन पर एक हस्ताक्षरित 16-बिट पूर्णांक (एक 'छोटा') है जहां 'int' 32-बिट मात्रा है, और यदि बाहर निकलने की स्थिति 128..255 की सीमा में है, तो WEXITSTATUS() अभी भी आपको एक सही मूल्य देता है जहां 256 तक विभाजित करना या सही स्थानांतरित करना आपको गलत मान देगा।

ऐसा इसलिए है क्योंकि लघु संकेत 32-बिट्स तक बढ़ाया जाएगा, और मुखौटा परिणाम में सही (सकारात्मक) मूल्य छोड़कर, साइन एक्सटेंशन को पूर्ववत करता है।

मशीन 16-बिट पूर्णांकों, तो WEXITSTATUS (में कोड का उपयोग किया है) है शायद तब समान व्यवहार सुनिश्चित करने के लिए मुखौटा बदलाव होगा:

#define WEXITSTATUS(status) (((status)>>8) & 0xFF) 

यह है कार्यान्वयन आप के लिए ऐसी जानकारी का ख्याल रखता है क्योंकि कि आपको WEXITSTATUS() मैक्रो का उपयोग करना चाहिए।

3

जहां तक ​​मेरा एकल यूनिक्स युक्ति जाँच से बता सकते हैं, अपने प्रणाली दूसरा सबसे दायां ओकटेट में बाहर निकलें स्थिति स्टोर करने के लिए होता है, लेकिन मैं नहीं मानता the standard करता है। इसलिए, आपको कम से कम कुछ कारणों से मैक्रोज़ का उपयोग करना चाहिए:

  • वे सही हैं। बिट-स्थानांतरण एक नकारात्मक संख्या विभिन्न प्लेटफार्मों पर अलग-अलग चीजें करता है। क्या यह आपके काम पर जिस तरह से काम करता है? मुझे नहीं पता।
  • वे सरल हैं। यह तुरंत स्पष्ट है कि WEXITSTATUS करता है। अन्य दृष्टिकोणों के साथ कम। यदि आपने WIFSIGNALED का हाथ से लुढ़का संस्करण देखा है, तो क्या आप इसे पहचान लेंगे? WIFSIGNALED से अधिक समय लगेगा।
  • वे पोर्टेबल हैं। चूंकि यह कहता है कि यह कैसे कहता है, यह हर प्रणाली पर काम करेगा (कम से कम हर यूनिक्स जैसी प्रणाली)।