目錄
1--進(jìn)程間通信
2--pipe()函數(shù)
3--代碼實(shí)例
3-1--pipe1.c
3-2--pipe2.c
3-3--pipe3.c
3-4--保存信息的回聲服務(wù)器端
1--進(jìn)程間通信
? ? ? ? 為了實(shí)現(xiàn)進(jìn)程間通信,使得兩個(gè)不同的進(jìn)程間可以交換數(shù)據(jù),操作系統(tǒng)必須提供兩個(gè)進(jìn)程可以同時(shí)訪問(wèn)的內(nèi)存空間;
? ? ? ? 為了完成進(jìn)程間通信,需要?jiǎng)?chuàng)建管道(pipe);管道并非屬于進(jìn)程的資源,而是屬于操作系統(tǒng);
2--pipe()函數(shù)
#include <unistd.h>
int pipe(int filedes[2]);
// 成功時(shí)返回0,失敗時(shí)返回-1
// filedes[0] 通過(guò)管道接收數(shù)據(jù)時(shí)使用的文件描述符,即管道出口
// filedes[1] 通過(guò)管道傳輸數(shù)據(jù)時(shí)使用的文件描述符,即管道入口
3--代碼實(shí)例
3-1--pipe1.c
? ? ? ? 子進(jìn)程從管道入口寫(xiě)數(shù)據(jù),父進(jìn)程從管道出口讀數(shù)據(jù);
// gcc pipe1.c -o pipe
// ./pipe
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30
int main(int argc, char *argv[]){
int fds[2];
char str[] = "Who are you?";
char buf[BUF_SIZE];
__pid_t pid;
pipe(fds); // 創(chuàng)建管道
pid = fork();
if(pid == 0){ // 子進(jìn)程執(zhí)行區(qū)域
write(fds[1], str, sizeof(str)); // 向管道入口寫(xiě)數(shù)據(jù)
}
else{ // 父進(jìn)程執(zhí)行區(qū)域
read(fds[0], buf, BUF_SIZE); // 向管道出口讀數(shù)據(jù)
puts(buf);
}
return 0;
}
3-2--pipe2.c
? ? ? ? 利用一個(gè)管道實(shí)現(xiàn)父進(jìn)程與子進(jìn)程的雙向通信;
// gcc pipe2.c -o pipe2
// ./pipe2
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30
int main(int argc, char *argv[]){
int fds[2];
char str1[] = "Who are you?";
char str2[] = "Thank you for your message";
char buf[BUF_SIZE];
__pid_t pid;
pipe(fds); // 創(chuàng)建管道
pid = fork();
if(pid == 0){ // 子進(jìn)程執(zhí)行區(qū)域
write(fds[1], str1, sizeof(str1));
sleep(2); // sleep的作用是防止子線程寫(xiě)的數(shù)據(jù)被子線程自身讀取了,導(dǎo)致父進(jìn)程一直等待
read(fds[0], buf, BUF_SIZE);
printf("Child proc output: %s \n", buf);
}
else{ // 父進(jìn)程執(zhí)行區(qū)域
read(fds[0], buf, BUF_SIZE);
printf("Parent proc output: %s \n", buf);
write(fds[1], str2, sizeof(str2));
sleep(3);
}
return 0;
}
3-3--pipe3.c
? ? ? ? 利用兩個(gè)管道實(shí)現(xiàn)父進(jìn)程與子進(jìn)程的雙向通信,其中收發(fā)數(shù)據(jù)在不同的管道上進(jìn)行;
// gcc pipe3.c -o pipe3
// ./pipe3
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30
int main(int argc, char *argv[]){
int fds1[2], fds2[2];
char str1[] = "Who are you?";
char str2[] = "Thank you for your message";
char buf[BUF_SIZE];
__pid_t pid;
pipe(fds1), pipe(fds2); // 創(chuàng)建管道
pid = fork();
if(pid == 0){ // 子進(jìn)程執(zhí)行區(qū)域
write(fds1[1], str1, sizeof(str1)); // 通過(guò)管道1寫(xiě)數(shù)據(jù)
read(fds2[0], buf, BUF_SIZE); // 通過(guò)管道2讀數(shù)據(jù)
printf("Child proc output: %s \n", buf);
}
else{ // 父進(jìn)程執(zhí)行區(qū)域
read(fds1[0], buf, BUF_SIZE); // 通過(guò)管道1讀數(shù)據(jù)
printf("Parent proc output: %s \n", buf);
write(fds2[1], str2, sizeof(str2)); // 通過(guò)管道2寫(xiě)數(shù)據(jù)
sleep(3);
}
return 0;
}
3-4--保存信息的回聲服務(wù)器端
? ? ? ? 服務(wù)器端創(chuàng)建兩個(gè)進(jìn)程,一個(gè)進(jìn)程負(fù)責(zé)與客戶端進(jìn)行通信,將客戶端發(fā)來(lái)的數(shù)據(jù)通過(guò)管道入口寫(xiě)到管道中;另一個(gè)進(jìn)程負(fù)責(zé)從管道出口中讀取數(shù)據(jù),并把讀取的數(shù)據(jù)保存在文件中;
? ? ? ? 具體可運(yùn)行代碼參考:Chapter11文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-703816.html
// gcc echo_storeserv.c -o echo_storeserv
// ./echo_storeserv 9190
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 30
void error_handling(char *message){
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
void read_childproc(int sig){
__pid_t pid;
int status;
pid = waitpid(-1, &status, WNOHANG);
printf("remove proc id: %d \n", pid);
}
int main(int argc, char* argv[]){
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
int fds[2];
__pid_t pid;
struct sigaction act; // 信號(hào)
socklen_t adr_sz;
int str_len, state;
char buf[BUF_SIZE];
if(argc != 2){
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
act.sa_handler = read_childproc; //設(shè)置信號(hào)處理函數(shù)
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
state = sigaction(SIGCHLD, &act, 0);
serv_sock = socket(PF_INET, SOCK_STREAM, 0); // 創(chuàng)建 tcp socket
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1){
error_handling("bind() error");
}
if(listen(serv_sock, 5) == -1){
error_handling("listen() error");
}
pipe(fds);
pid = fork();
if(pid == 0){ // 子進(jìn)程執(zhí)行區(qū)域
FILE* fp = fopen("echomsg.txt", "wt");
char msgbuf[BUF_SIZE];
int i, len;
for(i = 0; i < 10; i++){
len = read(fds[0], msgbuf, BUF_SIZE);
fwrite((void*)msgbuf, 1, len, fp);
}
fclose(fp);
return 0;
}
while(1){
adr_sz = sizeof(clnt_adr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);
if(clnt_sock == -1){
continue;
}
else{
puts("new client connected...");
}
pid = fork();
if(pid == 0){
close(serv_sock);
while((str_len = read(clnt_sock, buf, BUF_SIZE)) != 0){
write(clnt_sock, buf, str_len);
write(fds[1], buf, str_len);
}
close(clnt_sock);
puts("client disconnected...");
return 0;
}
else{
close(clnt_sock);
}
}
close(serv_sock);
return 0;
}
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-703816.html
到了這里,關(guān)于《TCP/IP網(wǎng)絡(luò)編程》閱讀筆記--進(jìn)程間通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!