网站排名查询软件,汉字logo标志设计,网页文章导入wordpress,网站托管 济南目录
1--进程间通信
2--pipe()函数
3--代码实例
3-1--pipe1.c
3-2--pipe2.c
3-3--pipe3.c
3-4--保存信息的回声服务器端 1--进程间通信 为了实现进程间通信#xff0c;使得两个不同的进程间可以交换数据#xff0c;操作系统必须提供两个进程可以同时访问的内存空间使得两个不同的进程间可以交换数据操作系统必须提供两个进程可以同时访问的内存空间 为了完成进程间通信需要创建管道pipe管道并非属于进程的资源而是属于操作系统 2--pipe()函数
#include unistd.h
int pipe(int filedes[2]);
// 成功时返回0失败时返回-1
// filedes[0] 通过管道接收数据时使用的文件描述符即管道出口
// filedes[1] 通过管道传输数据时使用的文件描述符即管道入口
3--代码实例
3-1--pipe1.c 子进程从管道入口写数据父进程从管道出口读数据 // gcc pipe1.c -o pipe
// ./pipe#include stdio.h
#include unistd.h
#define BUF_SIZE 30int main(int argc, char *argv[]){int fds[2];char str[] Who are you?;char buf[BUF_SIZE];__pid_t pid;pipe(fds); // 创建管道pid fork();if(pid 0){ // 子进程执行区域write(fds[1], str, sizeof(str)); // 向管道入口写数据}else{ // 父进程执行区域read(fds[0], buf, BUF_SIZE); // 向管道出口读数据puts(buf);}return 0;
} 3-2--pipe2.c 利用一个管道实现父进程与子进程的双向通信 // gcc pipe2.c -o pipe2
// ./pipe2#include stdio.h
#include unistd.h
#define BUF_SIZE 30int 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); // 创建管道pid fork();if(pid 0){ // 子进程执行区域write(fds[1], str1, sizeof(str1)); sleep(2); // sleep的作用是防止子线程写的数据被子线程自身读取了导致父进程一直等待read(fds[0], buf, BUF_SIZE);printf(Child proc output: %s \n, buf);}else{ // 父进程执行区域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 利用两个管道实现父进程与子进程的双向通信其中收发数据在不同的管道上进行 // gcc pipe3.c -o pipe3
// ./pipe3#include stdio.h
#include unistd.h
#define BUF_SIZE 30int 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); // 创建管道pid fork();if(pid 0){ // 子进程执行区域write(fds1[1], str1, sizeof(str1)); // 通过管道1写数据read(fds2[0], buf, BUF_SIZE); // 通过管道2读数据printf(Child proc output: %s \n, buf);}else{ // 父进程执行区域read(fds1[0], buf, BUF_SIZE); // 通过管道1读数据printf(Parent proc output: %s \n, buf);write(fds2[1], str2, sizeof(str2)); // 通过管道2写数据sleep(3);}return 0;
} 3-4--保存信息的回声服务器端 服务器端创建两个进程一个进程负责与客户端进行通信将客户端发来的数据通过管道入口写到管道中另一个进程负责从管道出口中读取数据并把读取的数据保存在文件中 具体可运行代码参考Chapter11 // 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 30void 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; // 信号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; //设置信号处理函数sigemptyset(act.sa_mask);act.sa_flags 0;state sigaction(SIGCHLD, act, 0);serv_sock socket(PF_INET, SOCK_STREAM, 0); // 创建 tcp socketmemset(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){ // 子进程执行区域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;}