像getpid()
這樣的調用背後的邏輯返回值pid_t
而不是unsigned int
的值是什麼?或者int
?這有什麼幫助?pid_t(和類似的類型) - 爲什麼,爲什麼?
我猜這與可移植性有關?保證pid_t
在不同平臺上的尺寸相同,可能有不同尺寸的int
等。
像getpid()
這樣的調用背後的邏輯返回值pid_t
而不是unsigned int
的值是什麼?或者int
?這有什麼幫助?pid_t(和類似的類型) - 爲什麼,爲什麼?
我猜這與可移植性有關?保證pid_t
在不同平臺上的尺寸相同,可能有不同尺寸的int
等。
我認爲情況正好相反:不管是否有PID(16位或32位)(甚至更長),都可以使程序跨平臺移植。
在不同的平臺和操作系統上,不同的類型(例如pid_t)可能是32位機器上的32位(無符號整數)或64位機器上的64位(無符號長整數)。或者,由於其他原因,操作系統可能會選擇不同的大小。此外,它在讀取代碼時明確表示這個變量代表一個「對象」,而不僅僅是一個任意數字。
原因是允許惡劣的歷史實現仍然符合。假設你的歷史實現了(而普通):
short getpid(void);
當然現代系統需要的PID至少爲32位,但如果標準規定:
int getpid(void);
那麼所有的歷史實現,有使用short
將變得不符合規定。這被認爲是不可接受的,所以pid_t
被創建並且允許實現以其更喜歡的方式定義pid_t
。
請注意,只要您使用足夠大的類型來存儲任何pid(例如,intmax_t
就可以正常工作),您絕不會在自己的代碼中使用pid_t
。 pid_t
需要存在的唯一原因是用標準來定義getpid
,waitpid
等。
啊,標準。得到它了。但是風格/最佳實踐呢?使用'pid_t'而不是'int'來持有pid會更好嗎?可讀性(明智地回答@Maz答案)?或者這是一件無足輕重的事情,它不應該得到這種關注? – ntl0ve
如果我可以加倍投票...但zvrbas的回答是這個答案的壓縮版本,所以我也會贊成zvrba。 –
使用'int'可能不是一個好主意,因爲它不支持使用64位pid的假想未來實現。我只是在大多數用途中使用'pid_t',但請記住,如果您有一個可以存儲具有大類型(即'intmax_t')的「泛型整數」的數據結構,那麼以這種方式存儲pid是可以接受的。 –
它的目的是使pid_t
或任何其他類型的平臺無關,以使它可以正常工作,無論它如何實際執行。這種做法被用於任何類型的需要與平臺無關,如:
pid_t
:必須足夠大,以存儲PID你編碼系統。就我所知,映射到int
,儘管我不是最熟悉GNU C庫的。size_t
:一個unsigned
變量能夠存儲運算符sizeof
的結果。大小通常與您正在編碼的系統的字號相同。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位的最快類型。通常,這是該系統的字的大小,如果(X <= word_size)
(或有時爲char
int_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)實現爲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.
}
如果使用這樣的,它可以幫助你什麼休息之前找到的代碼可能有問題的部分,並且可以使故障排除更容易比其他方式要好。
程序中的每個進程都有一個特定的進程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
父。
有一點需要指出的是,在大多數的答案,我看到沿着 「使用將爲pid_t使得不同系統的代碼工作」,這未必是真實的東西線。
我相信準確的措詞應該是:它使得代碼在不同的系統上「編譯」。
例如,如果在使用32位pid_t的系統上編譯代碼,則會生成一個二進制文件,如果在使用64位pid_t的另一個系統上運行,則該文件可能會損壞。
xiint8_t xint16_t xint32_t xint64_t之外的子類型整型不能解決任何問題:存在自動整數轉換。因此,合理年齡(比如10年)和規模(比如1MLOC)的每個現實世界計劃都包含1000個關於整數大小的無法檢測的靜默假設。 – zzz777
@ zzz777天啊,真的... – Ivan