2011-09-11 49 views

回答

32

我認爲情況正好相反:不管是否有PID(16位或32位)(甚至更長),都可以使程序跨平臺移植。

+1

xiint8_t xint16_t xint32_t xint64_t之外的子類型整型不能解決任何問題:存在自動整數轉換。因此,合理年齡(比如10年)和規模(比如1MLOC)的每個現實世界計劃都包含1000個關於整數大小的無法檢測的靜默假設。 – zzz777

+0

@ zzz777天啊,真的... – Ivan

9

在不同的平臺和操作系統上,不同的類型(例如pid_t)可能是32位機器上的32位(無符號整數)或64位機器上的64位(無符號長整數)。或者,由於其他原因,操作系統可能會選擇不同的大小。此外,它在讀取代碼時明確表示這個變量代表一個「對象」,而不僅僅是一個任意數字。

26

原因是允許惡劣的歷史實現仍然符合。假設你的歷史實現了(而普通):

short getpid(void); 

當然現代系統需要的PID至少爲32位,但如果標準規定:

int getpid(void); 

那麼所有的歷史實現,有使用short將變得不符合規定。這被認爲是不可接受的,所以pid_t被創建並且允許實現以其更喜歡的方式定義pid_t

請注意,只要您使用足夠大的類型來存儲任何pid(例如,intmax_t就可以正常工作),您絕不會在自己的代碼中使用pid_tpid_t需要存在的唯一原因是用標準來定義getpidwaitpid等。

+0

啊,標準。得到它了。但是風格/最佳實踐呢?使用'pid_t'而不是'int'來持有pid會更好嗎?可讀性(明智地回答@Maz答案)?或者這是一件無足輕重的事情,它不應該得到這種關注? – ntl0ve

+0

如果我可以加倍投票...但zvrbas的回答是這個答案的壓縮版本,所以我也會贊成zvrba。 –

+0

使用'int'可能不是一個好主意,因爲它不支持使用64位pid的假想未來實現。我只是在大多數用途中使用'pid_t',但請記住,如果您有一個可以存儲具有大類型(即'intmax_t')的「泛型整數」的數據結構,那麼以這種方式存儲pid是可以接受的。 –

6

它的目的是使pid_t或任何其他類型的平臺無關,以使它可以正常工作,無論它如何實際執行。這種做法被用於任何類型的需要與平臺無關,如:

  • pid_t:必須足夠大,以存儲PID你編碼系統。就我所知,映射到int,儘管我不是最熟悉GNU C庫的。
  • size_t:一個unsigned變量能夠存儲運算符sizeof的結果。大小通常與您正在編碼的系統的字號相同。
  • int16_tintX_t):無論平臺如何,都必須是正好16位,並且不會在不支持8位字節的平臺(如36位系統)上定義。通常在現代計算機上映射到short,但在較舊的計算機上可能是int
  • int_least32_tint_leastX_t):必須是可以存儲至少32位(例如36位或72位系統上的36位)的最小可能大小。通常在現代計算機上映射到int,但在較舊的計算機上可能是long
  • int_fastX_t:必須是可以存儲至少X位的最快類型。通常,這是該系統的字的大小,如果(X <= word_size)(或有時爲charint_fast8_t),或作用就像int_leastX_t如果(X > word_size)
  • intmax_t:必須由系統支持的最大整數寬度。通常,在現代系統上它至少有64位,但有些系統可能支持大於long long的擴展類型(如果需要,intmax_t需要是這些類型中最大的)。
  • 更多...

機械,它可以讓編譯器的安裝程序typedef適當類型標識符(無論是標準型或笨拙地命名內部類)幕後,無論是通過創造合適頭文件,將其編碼到編譯器的可執行文件或其他方法中。例如,在32位系統上,微軟的Visual Studio將實施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位系統,然而,他們可能不必須以相同的方式實現,並且我可以保證,如果您可以找到與其兼容的MSVS版本,那麼它們將不會在古老的16位系統上以相同的方式實現。總體而言,無論您的實施細節如何,它都允許代碼正常工作,並在任何兼容標準的系統上滿足相同的要求(例如,pid_t可以保證足夠大以保持系統上的任何有效PID在問題中,不管你編碼的是什麼系統)。它還可以防止你必須知道本質,並且不必查找你可能不熟悉的內部名字。簡而言之,無論pid_t(或任何其他類似的typedef)實現爲intshortlonglong 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

程序中的每個進程都有一個特定的進程ID。通過調用pid,我們知道當前進程的分配標識。當我們使用fork()時,知道該pid非常重要,因爲它會以可接受的方式返回子版本和父版本的0!=0值。這兩部影片有明確的解釋:video#1Video#2

一個例子:假設我們有下面的C程序:

#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的另一個系統上運行,則該文件可能會損壞

相關問題