#include #include #include #include #include #include #include int main()
; pid_t pid;
int ret=0;
int fd = open("./temp.txt", o_creat|o_trunc|o_rdwr, 0666);
if( fd == -1 )
if ((pid = fork()) < 0)
else if (pid == 0)
else
waitpid(pid, null, 0);
return 0;
}
執行結果如下:
[root@lghvm001 multi_process]# gcc inherit_fd.c
[root@lghvm001 multi_process]# ./a.out
[root@lghvm001 multi_process]# cat temp.txt
parent process pid:18028, child pid:18029
child process pid:18029,parent pid:18028
結論:子程序繼承了父程序已經開啟了的檔案描述符。
寫乙個簡單的tcp server回射程式,即客戶端給伺服器端發一段字串,伺服器端將字串原樣返回。這裡伺服器端的server程式採用主程序+工作程序的模式:主程序負責接收客戶端的連線請求,然後fork乙個子程序(也叫工作程序)來處理客戶端的請求資料,即子程序接收客戶端發來的字串,然後將字串原樣返回給客戶端。這裡主要演示子程序繼承父程序的tcp socket,下面來看**:
tcp_server.c
/* tcp_server.c */
#include #include #include #include #include #include #include #include #include #include #include #define maxline 1024
#define backlog 50
int main(int argc, char** argv)
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = af_inet; //ipv4
servaddr.sin_addr.s_addr = htonl(inaddr_any); //自動填入本機的ip位址
/*if( inet_pton(af_inet, "172.23.1.180", &servaddr.sin_addr) <= 0)
*/servaddr.sin_port = htons(6666); //將埠號轉換為網路位元組序
if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
if( listen(listenfd, backlog) == -1)
printf("*****=waiting for client's connect requestion*****=\n");
while(1)
if ((pid = fork()) < 0)
else if (pid == 0)
buff[n] = '\0';
fputs("recv msg from client: ", stdout);
fputs(buff, stdout);
while (n > 0)
if((n = recv(connfd, buff, maxline-1, 0)) < 0)
buff[n] = '\0';
fputs(buff, stdout);
} close(connfd);
exit(0);
} else
} return 0;
}
客戶端**tcp_client.c
/* tcp_client.c */
#include#include#include#include#include#include#include#define maxline 1024
int main(int argc, char** argv)
*/
memset(recvline, 0, maxline);
memset(sendline, 0, maxline);
if( (sockfd = socket(af_inet, sock_stream, 0)) < 0)
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_port = htons(6666);
servaddr.sin_addr.s_addr = htonl(inaddr_any);
/* if( inet_pton(af_inet, argv[1], &servaddr.sin_addr) <= 0)*/
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
printf("send msg to server: \n");
while(1)
fputs("echo from server:\n", stdout);
received = 0;
while(received < len)
else if(bytes == 0)
received += bytes;
recvline[bytes] = '\0';
fputs(recvline, stdout);
} fputs("\n", stdout);
}
close(sockfd);
return 0;
}
開啟linux的命令列終端,編譯執行tcp_server
另外再開啟兩個命令列終端,編譯執行tcp_client
執行結果如下:
tcp_server
[root@lghvm001 multi_process]# gcc tcp_server.c -o tcp_server
[root@lghvm001 multi_process]# ./tcp_server
*****=waiting for client's connect requestion*****=
connected, client addr: 255.127.0.0
recv msg from client: hi,this is client1.
connected, client addr: 127.0.0.1
recv msg from client: hi, this is client2.
tcp_client1
[root@lghvm001 multi_process]# gcc tcp_client.c -o tcp_client
[root@lghvm001 multi_process]# ./tcp_client
send msg to server:
hi,this is client1.
echo from server:
hi,this is client1.
tcp_client2
[lgh@lghvm001 multi_process]$ ./tcp_client
send msg to server:
hi, this is client2.
echo from server:
hi, this is client2.
該示例有多少個客戶端連線就會產生多少個子程序,目前有主程序,兩個子程序:
[lgh@lghvm001 desktop]$ ps -ef | grep tcp_server
root 18302 43605 0 14:08 pts/14 00:00:00 ./tcp_server
root 18309 18302 0 14:09 pts/14 00:00:00 ./tcp_server
root 18311 18302 0 14:09 pts/14 00:00:00 ./tcp_server
lgh 18313 18132 0 14:09 pts/22 00:00:00 grep tcp_server
[lgh@lghvm001 desktop]$
若客戶端連線太多,會導致多過的子程序,可以使用多路io復用進行優化,在linux下epoll是不二選擇。
子程序繼承父程序中互斥鎖的討論
1.引言 首先明確乙個問題 如果乙個多執行緒程式的某個執行緒呼叫了fork函式,那麼新建立的子程序裡是不會自動建立和父程序相同數量的執行緒的,它只是呼叫fork的那個執行緒的完整複製。並且,子程序會自動繼承父程序中 包括父程序在呼叫fork之前建立的執行緒 互斥鎖的狀態。也就是說,父程序中已經被加鎖...
Linux中建立新的程序,父程序等待子程序的退出
乙個程序可以呼叫fork 來複製自己,複製的時候這兩個程序完全相同,之後便分道揚鑣。標頭檔案 include 函式原型 pid t result fork void 返回值 根據不同的返回值,可以判斷當前執行的是子程序還是父程序 父程序呼叫wait函式等待子程序退出 標頭檔案 include inc...
fork 子程序不繼承父程序開啟的檔案描述符
昨天面試被問到了這個問題,沒有回答上來,網上找了一下答案。解決方法是使用clone系統呼叫使用引數在複製時將父程序資源有選擇地複製給子程序。下面介紹forkvforkclone三者的區別 vfork系統呼叫不同於fork,用vfork建立的子程序與父程序共享位址空間,也就是說子程序完全執行在父程序的...