2011-09-11 12 views
35

getpid() जैसे कॉल के पीछे तर्क के बजाय pid_t का मान लौटा रहा है? या int? यह कैसे मदद करता है?pid_t (और इसी तरह के प्रकार) - क्यों, बस क्यों?

मुझे लगता है कि पोर्टेबिलिटी के साथ इसका संबंध है? गारंटी है कि pid_t अलग-अलग प्लेटफॉर्म पर एक ही आकार है जिसमें int आदि के विभिन्न आकार हो सकते हैं?

उत्तर

32

मुझे लगता है कि यह विपरीत है: इस कार्यक्रम को प्लेटफॉर्म पर पोर्टेबल बनाने के बावजूद, चाहे पीआईडी ​​16 या 32 बिट्स (या इससे भी अधिक) हो।

+1

xiint8_t xint16_t xint32_t xint64_t से परे उप-टाइपिंग पूर्णांक किसी भी समस्या का समाधान नहीं करता है: वहां स्वचालित पूर्णांक रूपांतरण होते हैं। इसलिए उचित उम्र के प्रत्येक वास्तविक दुनिया कार्यक्रम (10 साल का कहना है) और आकार (1 एमएमओसी कहें) में पूर्णांक आकारों के बारे में ज्ञानी चुप धारणाओं के 1000s शामिल हैं। – zzz777

+0

@ zzz777 हे भगवान, इतना सच ... – Ivan

9

विभिन्न प्लेटफॉर्म और ऑपरेटिंग सिस्टम पर, विभिन्न प्रकार (उदाहरण के लिए pid_t) 32-बिट मशीन पर 32 बिट्स (हस्ताक्षरित int) या 64-बिट मशीन पर 64 बिट्स (हस्ताक्षरित लंबे) हो सकते हैं। या, किसी अन्य कारण से, एक ऑपरेटिंग सिस्टम का आकार अलग-अलग हो सकता है। इसके अतिरिक्त, यह कोड को पढ़ने पर यह स्पष्ट करता है कि यह चर केवल एक मनमानी संख्या के बजाय "ऑब्जेक्ट" का प्रतिनिधित्व करता है।

26

कारण ऐतिहासिक ऐतिहासिक कार्यान्वयन अभी भी अनुकूल होना है। मान लीजिए कि आपके ऐतिहासिक कार्यान्वयन था (न कि आम):

short getpid(void); 
पाठ्यक्रम आधुनिक प्रणालियों पीआईडी ​​की कम से कम 32-बिट होना चाहता हूँ के

, लेकिन अगर मानक अनिवार्य:

int getpid(void); 

तो सभी ऐतिहासिक कार्यान्वयन कि था प्रयुक्त short गैर-अनुरूप बन जाएगा। इसे अस्वीकार्य समझा जाता था, इसलिए pid_t बनाया गया था और कार्यान्वयन को pid_t को जिस तरह से पसंद किया गया है उसे परिभाषित करने की अनुमति थी।

ध्यान दें कि आप अपने कोड में pid_t का उपयोग करने के लिए बाध्य नहीं हैं जब तक कि आप किसी भी प्रकार का उपयोग करने के लिए पर्याप्त नहीं हैं, उदाहरण के लिए intmax_t उदाहरण के लिए ठीक काम करेगा)। pid_tको की आवश्यकता का एकमात्र कारण getpid, waitpid आदि को परिभाषित करने के मानक के लिए है।

+0

आह, मानकों। समझ गया। लेकिन शैली/सर्वोत्तम अभ्यास के बारे में क्या? क्या एक पिड रखने के लिए 'int' की तुलना में 'pid_t' का उपयोग करना बेहतर है? पठनीयता-वार (@Maz उत्तर की ओर इशारा करते हुए)? या यह इतनी छोटी और अर्थहीन बात है कि यह इस तरह के ध्यान के लायक नहीं है? – ntl0ve

+0

यदि मैं दो बार वोट दे सकता हूं ... लेकिन zvrbas उत्तर इस उत्तर के संपीड़ित संस्करण की तरह है, इसलिए मैं zvrba को भी ऊपर उठाऊंगा। –

+0

'int' का उपयोग करना शायद एक अच्छा विचार नहीं है क्योंकि यह 64-बिट पिड्स के साथ काल्पनिक भविष्य के कार्यान्वयन का समर्थन नहीं करेगा। मैं ज्यादातर उपयोगों के लिए 'pid_t' का उपयोग करता हूं, लेकिन ध्यान रखें कि यदि आपके पास डेटा संरचना है जो "जेनेरिक पूर्णांक" को बड़े प्रकार के साथ स्टोर कर सकती है (यानी' intmax_t') तो यह उस तरह से पिड्स स्टोर करने के लिए स्वीकार्य होगा। –

6

इसका उद्देश्य pid_t, या किसी अन्य प्रकार के सॉफ़्टवेयर, प्लेटफॉर्म-स्वतंत्र बनाना है, जैसे कि यह वास्तव में कैसे कार्यान्वित किया जाता है इस पर ध्यान दिए बिना ठीक से काम करता है।

  • pid_t: इस अभ्यास किसी भी प्रकार, जैसे कि मंच स्वतंत्र होने की जरूरत है के लिए प्रयोग किया जाता है इतना बड़ा प्रणाली आप के लिए कोडिंग कर रहे हैं पर एक पीआईडी ​​स्टोर करने के लिए किया जाना है। जहां तक ​​मुझे पता है, int पर मैप्स, हालांकि मैं जीएनयू सी लाइब्रेरी से सबसे परिचित नहीं हूं।
  • size_t: unsignedsizeof ऑपरेटर के परिणाम को संग्रहीत करने में सक्षम चर। आम तौर पर सिस्टम के शब्द आकार के आकार में बराबर है जिसके लिए आप कोडिंग कर रहे हैं।
  • int16_t (intX_t): मंच के बावजूद बिल्कुल 16 बिट्स होना चाहिए, और प्लेटफ़ॉर्म पर परिभाषित नहीं किया जाएगा जो 8-बिट बाइट्स (जैसे 36-बिट सिस्टम) का समर्थन नहीं करते हैं। आम तौर पर आधुनिक कंप्यूटर पर short पर मानचित्र, हालांकि यह पुराने लोगों पर int हो सकता है।
  • int_least32_t (int_leastX_t): कम से कम 32 बिट्स स्टोर कर सकते हैं, जैसे 36 बिट्स या 72-बिट सिस्टम पर 36 बिट्स स्टोर कर सकते हैं।आम तौर पर आधुनिक कंप्यूटर पर int पर नक्शा, हालांकि यह पुराने लोगों पर long हो सकता है।
  • int_fastX_t: सबसे तेज़ प्रकार संभव होना चाहिए जो कम से कम एक्स बिट्स स्टोर कर सके। आम तौर पर, यह सिस्टम के शब्द आकार अगर (X <= word_size) (या कभी कभी int_fast8_t के लिए char), या की तरह int_leastX_t(X > word_size) अगर)
  • intmax_t में कार्य करता है: अधिकतम पूर्णांक चौड़ाई प्रणाली द्वारा समर्थित होना चाहिए। आम तौर पर, यह आधुनिक प्रणालियों पर कम से कम 64 बिट्स होगा, हालांकि कुछ सिस्टम long long से बड़े प्रकार के विस्तारित प्रकार का समर्थन कर सकते हैं (और यदि ऐसा है, तो intmax_t उन प्रकारों में से सबसे बड़ा होना आवश्यक है)।
  • और अधिक ...

यंत्रवत्, यह typedef को संकलक के संस्थापक की अनुमति देता है पहचानकर्ता को उचित प्रकार (चाहे एक मानक प्रकार या एक awkwardly नाम आंतरिक प्रकार) पर्दे के पीछे, उचित बनाने के द्वारा है कि क्या हेडर फाइलें, इसे कंपाइलर के निष्पादन योग्य, या किसी अन्य विधि में कोडिंग करें। (: मेरे द्वारा टिप्पणियां जोड़ी टिप्पणी): उदाहरण के लिए, एक 32-बिट सिस्टम पर, माइक्रोसॉफ्ट विजुअल स्टूडियो intX_t और इसी तरह के प्रकार निम्नानुसार को लागू करेगा

// Signed ints of exactly X bits. 
typedef signed char int8_t; 
typedef short int16_t; 
typedef int int32_t; 

// Unsigned ints of exactly X bits. 
typedef unsigned char uint8_t; 
typedef unsigned short uint16_t; 
typedef unsigned int uint32_t; 

// Signed ints of at least X bits. 
typedef signed char int_least8_t; 
typedef short int_least16_t; 
typedef int int_least32_t; 

// Unsigned ints of at least X bits. 
typedef unsigned char uint_least8_t; 
typedef unsigned short uint_least16_t; 
typedef unsigned int uint_least32_t; 

// Speed-optimised signed ints of at least X bits. 
// Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word. 
typedef char int_fast8_t; 
typedef int int_fast16_t; 
typedef int int_fast32_t; 

// Speed-optimised unsigned ints of at least X bits. 
typedef unsigned char uint_fast8_t; 
typedef unsigned int uint_fast16_t; 
typedef unsigned int uint_fast32_t; 

typedef _Longlong int64_t; 
typedef _ULonglong uint64_t; 

typedef _Longlong int_least64_t; 
typedef _ULonglong uint_least64_t; 

typedef _Longlong int_fast64_t; 
typedef _ULonglong uint_fast64_t; 

एक 64-बिट सिस्टम पर, तथापि, वे नहीं हो सकता जरूरी रूप से उसी तरह लागू किया जाना चाहिए, और मैं गारंटी दे सकता हूं कि उन्हें एक पुरातन 16-बिट सिस्टम पर उसी तरह लागू नहीं किया जाएगा, यह मानते हुए कि आप एक के साथ संगत एमएसवीएस का एक संस्करण पा सकते हैं।

कुल मिलाकर, यह कोड अपने कार्यान्वयन की बारीकियों की परवाह किए बिना ठीक से काम करने, और किसी भी मानक-संगत प्रणाली पर एक ही आवश्यकताओं को पूरा करने की अनुमति देता है (pid_t इतना बड़ा सिस्टम पर किसी भी वैध पीआईडी ​​धारण करने के लिए होने की गारंटी दी जा सकती जैसे सवाल में, कोई फर्क नहीं पड़ता कि आप किस प्रणाली के लिए कोडिंग कर रहे हैं)। यह आपको नट-किरकिरा जानने से रोकता है, और आंतरिक नामों को देखने से आपको परिचित नहीं हो सकता है। संक्षेप में, यह सुनिश्चित करता है कि आपका कोड pid_t (या किसी अन्य समान टाइपिफ़) को int, short, long, long long, या यहां तक ​​कि __Did_you_really_just_dare_me_to_eat_my_left_shoe__ के रूप में लागू किया गया है, तो आपको यह भी काम करता है।


इसके अतिरिक्त, यह बताने के लिए क्या एक दिया चर एक नज़र में के लिए है की अनुमति देता है, प्रलेखन के रूप में कार्य करता है।

int a, b; 

.... 

if (a > b) { 
    // Nothing wrong here, right? They're both ints. 
} 

अब, चलो फिर से कोशिश करते हैं: निम्नलिखित पर विचार करें

size_t a; 
pid_t b; 

... 

if (a > b) { 
    // Why are we comparing sizes to PIDs? We probably messed up somewhere. 
} 

अगर इस तरह के रूप में इस्तेमाल किया, यह मदद कर सकते हैं कुछ भी टूट जाता है से पहले कोड के संभावित रूप से समस्या क्षेत्रों का पता लगाने, और समस्या निवारण बहुत आसान बना सकते हैं अन्यथा यह होगा।

2

कार्यक्रम में प्रत्येक प्रक्रिया में एक विशिष्ट प्रक्रिया आईडी है। पिड को कॉल करके, हम वर्तमान प्रक्रिया की निर्दिष्ट आईडी को जानते हैं। जब हम fork() का उपयोग करते हैं तो पिड को जानना बेहद महत्वपूर्ण है, क्योंकि यह 0 और !=0 मूल्यों को बच्चे और माता-पिता प्रतियों के लिए विश्वसनीय रूप से देता है।इन दो वीडियो स्पष्ट व्याख्या है: video#1Video#2

एक उदाहरण: मान लीजिए कि हमें निम्नलिखित ग कार्यक्रम है:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 


int main (int argc, char *argv[]) 
{ 

    printf("I am %d\n", (int) getpid()); 
    pid_t pid = fork(); 
    printf("fork returned: %d\n", (int) pid); 
    if(pid<0){ 
    perror("fork failed"); 
    } 
    if (pid==0){ 
    printf("This is a child with pid %d\n",(int) getpid()); 
    }else if(pid >0){ 
    printf("This is a parent with pid %d\n",(int)getpid()); 
    } 

    return 0; 
} 

आप इसे चलाते हैं, तो आप माता-पिता के लिए बच्चे के लिए 0 और गैर zero/greater than zero मिल जाएगा।

0

एक बात बताते हैं, सबसे जवाब में मैं के , जो जरूरी सच नहीं है "pid_t का उपयोग कर विभिन्न प्रणालियों पर कोड काम करता है" पंक्तियों के साथ कुछ देखा।

मेरा मानना ​​है कि सटीक शब्द होना चाहिए: यह विभिन्न सिस्टम पर कोड 'संकलन' बनाता है।

के रूप में, उदाहरण के लिए, एक प्रणाली 32-बिट pid_t का उपयोग करता है एक द्विआधारी कि शायद तोड़ अगर किसी अन्य सिस्टम 64-बिट pid_t का उपयोग करता है पर चलेगा उत्पादन करेगा पर कोड संकलन।

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