Linux 程序間通訊 管道
阿新 • • 發佈:2019-01-24
管道
匿名管道:半雙工,資料單向流動,只能用與有親緣關係的程序間。
pipe_read_buf_small.c
#include <unistd.h> #include <sys/types.h> int main(){ int pipe_fd[2]; pid_t pid; // char* r_buf; // char* w_buf; char r_buf[4096]; char w_buf[4096*2]; int r_num; int w_num; int count=0; if(pipe(pipe_fd)==-1){ printf("Crate pipe error\n"); } if((pid=fork())<0){ printf("Fork error\n"); }else if(pid==0){ printf("Child:\n"); close(pipe_fd[1]); while(1){ sleep(1); if((r_num=read(pipe_fd[0],r_buf,1000))==-1){ printf("Child read error\n"); }else { printf("Child read successfully read:%d\n",r_num); } count++; if(count>10){ break; } } close(pipe_fd[0]); printf("c dead\n"); exit(0); }else{ printf("Parent:\n"); close(pipe_fd[0]); if((w_num=write(pipe_fd[1],w_buf,1024))<0){ printf("p write error\n"); }else{ printf("p write successfully :%d\n",w_num); } w_num=write(pipe_fd[1],w_buf,4096); printf("p write suc 2 :%d\n",w_num); printf("p dead\n"); exit(0); } return 0; }
pipe_close_child_read.c
#include <sys/types.h> #include <errno.h> #include <sys/types.h> int main(){ int pipe_fd[2]; pid_t pid; // char* r_buf; // char* w_buf; char r_buf[4096]; char w_buf[4096*2]; int r_num; int w_num; int count=0; if(pipe(pipe_fd)==-1){ printf("Crate pipe error\n"); } if((pid=fork())<0){ printf("Fork error\n"); }else if(pid==0){ printf("Child:\n"); close(pipe_fd[1]); while(1){ sleep(1); if((r_num=read(pipe_fd[0],r_buf,1000))==-1){ printf("Child read error\n"); }else { printf("Child read successfully read:%d\n",r_num); } count++; if(count>10){ break; } } close(pipe_fd[0]); printf("c dead\n"); exit(0); }else{ printf("Parent:\n"); close(pipe_fd[0]); if((w_num=write(pipe_fd[1],w_buf,1024))<0){ printf("p write error\n"); }else{ printf("p write successfully :%d\n",w_num); } w_num=write(pipe_fd[1],w_buf,4096); printf("p write suc 2 :%d\n",w_num); printf("p dead\n"); exit(0); } return 0; }
pipe_close_parent_write.c
#include <unistd.h> #include <sys/types.h> #include <errno.h> int main(){ int pipe_fd[2]; pid_t pid; char r_buf[10]; char w_buf[4]; int r_num; if(pipe(pipe_fd)==-1){ printf("Open pipe error\n"); return -1; } if((pid=fork())<0){ printf("Fork error\n"); }else if(pid==0){ printf("Child process\n"); close(pipe_fd[1]);//close write sleep(3);//make sure the parent process close write r_num=read(pipe_fd[0],r_buf,10); //printf("Read size:%d,%d\n",r_num,atoi(r_buf)); printf("Read size:%d,%s\n",r_num,r_buf); close(pipe_fd[0]); printf("Child dead!\n"); exit(0); }else if(pid>0){ printf("Parent process\n"); close(pipe_fd[0]);//close read strcpy(w_buf,"123"); if(write(pipe_fd[1],w_buf,5)!=-1){ printf("Write successfully\n"); } close(pipe_fd[1]); printf("Parent process write has been closed!\n"); // sleep(6); printf("Parent dead!\n"); exit(0); } exit(0); }
命名管道:可以在不具有親緣關係的程序間通訊。
FIFO_w.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#define FIFO_SERVER "/tmp/fifoserver"
int main(){
int fd;
char w_buf[4096*2];
int w_num;
if(mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)<0){
printf("Create fifo error\n");
}
// fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
fd=open(FIFO_SERVER,O_WRONLY,0);
if(fd==-1){
if(errno==ENXIO){
printf("open error;no reading process\n");
}
}
memset(w_buf,0,4096*2);
w_num=write(fd,w_buf,2048);
if(w_num==-1){
if(errno==EAGAIN){
printf("1write to fifo error, try later\n");
}
}else {
printf("1write successfully:%d\n",w_num);
}
w_num=write(fd,w_buf,5000);
if(w_num==-1){
if(errno==EAGAIN){
printf("2write to fifo error, try later\n");
}
}else {
printf("2write successfully:%d\n",w_num);
}
return 0;
}
FIFO_r.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#define FIFO_SERVER "/tmp/fifoserver"
#define SIZE 4096
int main(int argc,char **argv){
char r_buf[SIZE];
int fd;
int r_num=atoi(argv[1]);
printf("Read wants to read:%d\n",r_num);
//fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0);
fd=open(FIFO_SERVER,O_RDONLY,0);
if(fd==-1){
printf("open %s for read error\n",FIFO_SERVER);
exit(0);
}
int count=0;
while(1){
r_num=read(fd,r_buf,SIZE);
if(r_num==-1){
if(errno==EAGAIN)
printf("no data available\n");
}else {
printf("read OK :%d\n",r_num);
}
sleep(1);
count++;
if(count>20)break;
}
unlink(FIFO_SERVER);
return 0;
}
參考鄭彥興《Linux程序通訊》