[英]Dynamic pool of processes
我正在Unix系統上用C編寫一個客戶端-服務器(TCP)程序。 客戶端發送一些信息,服務器回答。 每個子進程只有一個連接。 新的連接使用池中的預運行進程,並且池的大小是動態的,因此,如果空閑進程(不為客戶端提供服務的進程)的數量減少得太少,則它應該創建新的進程,如果它變得過高,則同樣會創建額外的進程進程應終止。
這是我的服務器代碼。 每個連接都使用fork()
創建一個新的子進程。 每個連接都在新進程中運行。 我如何像上面解釋的那樣建立一個動態池?
int main(int argc, char * argv[])
{
int cfd;
int listener = socket(AF_INET, SOCK_STREAM, 0); //create listener socket
if(listener < 0){
perror("socket error");
return 1;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
int binding = bind(listener, (struct sockaddr *)&addr, sizeof(addr));
if(binding < 0){
perror("binding error");
return 1;
}
listen(listener, 1); //listen for new clients
signal(SIGCHLD,handler);
int pid;
for(;;) // infinity loop on server
{
cfd = accept(listener, NULL, NULL); //client socket descriptor
pid = fork(); //make child proc
if(pid == 0) //in child proc...
{
close(listener); //close listener socket descriptor
... //some server actions that I do.(receive or send)
close(cfd); // close client fd
return 0;
}
close(cfd);
}
如果您在同一個偵聽套接字上阻止了多個進程accept
,則進入的新連接將傳遞給其中一個。 (取決於,可能會喚醒幾個,但實際上只有一個會連接)。 因此,您需要在listen
之后但accept
之前分叉幾個孩子。 處理完請求后,孩子返回accept
而不是exit
。 處理(1)和(2)。
(3)比較難。 您需要某種形式的IPC。 通常,您將擁有一個父進程,該進程僅負責管理正確數量的子進程。 您的子進程需要使用IPC來告訴父進程他們有多忙。 然后,父母可以分叉更多的孩子(進入上面的accept
循環),也可以向孩子發送信號以告訴他們完成並退出。 它還應處理對孩子的wait
,處理意外死亡等。
您要使用的IPC可能是共享內存。 您的兩個選項是SysV( shmget) and POSIX (
shm_open`)共享內存。 如果可能,您可能需要后者。 您將不得不處理同步訪問(POSIX和SysV提供信號量來幫助解決此問題,再次偏愛POSIX)或僅使用原子訪問。
(您實際上可能不希望有一個超過X個免費子級的進程立即退出,這會導致反復收獲和生成它們,這很昂貴。相反,您可能想要某種程度的度量,以了解它們在整個過程中的利用率如何。最后一秒...因此,您的數據比正在使用/免費的位圖更復雜。)
有許多這樣的守護程序,因此您可以輕松地找到代碼示例。 當然,如果您查看Apache,您可能會發現它更加復雜,從而獲得良好的性能並可以隨處移植。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.