您好,登錄后才能下訂單哦!
sockpair實(shí)現(xiàn)進(jìn)程間通信
我們以前學(xué)習(xí)的利用管道(此處為匿名管道)實(shí)現(xiàn)進(jìn)程間通信,只能是單向的,一邊只能讀而另一邊只能寫,且只能在有血緣關(guān)系的進(jìn)程間才能通信,若想實(shí)現(xiàn)雙向通信就必須創(chuàng)建雙向管道,而sockpair它的實(shí)現(xiàn)就是雙向管道進(jìn)行通信。它可以用來創(chuàng)建雙向通信管道
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<sys/socket.h> 6 #include<stdlib.h> 7 #include<errno.h> 8 9 int main() 10 { 11 int sv[2]={0,0}; 12 char buf[1024]; 13 int sock_pair=socketpair(AF_LOCAL,SOCK_STREAM,0,sv); 14 if(sock_pair < 0) 15 { 16 perror("socketpair"); 17 exit(1); 18 } 19 pid_t id=fork(); 20 if(id<0) 21 { 22 perror("fork"); 23 return -1;
24 }else if(id==0){ //child 25 close(sv[0]); 26 while(1) 27 { 28 memset(buf,'\0',sizeof(buf)); 29 strcpy(buf,"I'm child"); 30 write(sv[1],buf,strlen(buf)); 31 ssize_t _size=read(sv[1],buf,sizeof(buf)-1); 32 if(_size<0) 33 { 34 perror("read"); 35 return -2; 36 }else if(_size > 0) 37 { 38 buf[_size]='\0'; 39 printf("father->child:%s\n",buf); 40 } 41 sleep(1); 42 } 43 close(sv[1]); 44 45 }else 46 { 47 close(sv[1]); 48 while(1) 49 { 50 ssize_t _size=read(sv[0],buf,sizeof(buf)-1); 51 if(_size<0) 52 { 53 perror("read"); 54 exit(2); 55 }else if(_size >0) 56 { 57 buf[_size]='\0'; 58 printf("child->father:%s\n",buf); 59 } 60 // memset(buf,'\0',sizeof(buf)); 61 strcpy(buf,"I'm father"); 62 write(sv[0],buf,sizeof(buf)-1); 63 } 64 close(sv[0]); 65 } 66 return 0; 67 }
程序運(yùn)行結(jié)果:
重定向:對文件描述符進(jìn)行重定向
例:將一個文件中的內(nèi)容打印到標(biāo)準(zhǔn)輸出上,若關(guān)閉了標(biāo)準(zhǔn)輸出文件描述符,此時再打開一個文件,文件描述符將為1,而此時第一個文件的內(nèi)容將會被打印到文件中(即重定向)
若新創(chuàng)建一個進(jìn)程文件描述符會從3(若0、1、2都不關(guān))開始?
當(dāng)打開一個終端時,該過程即為創(chuàng)建一個會話的過程,會有一個控制進(jìn)程bash,也就是會話首進(jìn)程,關(guān)聯(lián)terminal終端后會默認(rèn)填上標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出以及標(biāo)準(zhǔn)錯誤,因此在當(dāng)下創(chuàng)建的進(jìn)程都為子進(jìn)程,又因子進(jìn)程在創(chuàng)建時會繼承父進(jìn)程的文件描述符,因此創(chuàng)建一個進(jìn)程后文件描述符會從3開始。
使用dup重定向:函數(shù)原型 int dup(int oldfd)
例:關(guān)閉1號文件描述符(標(biāo)準(zhǔn)輸出),本應(yīng)將標(biāo)準(zhǔn)輸入的內(nèi)容打印到標(biāo)準(zhǔn)輸出上,重定向到了log文件中
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<fcntl.h> 5 #include<string.h> 6 #include<errno.h> 7 #include<sys/stat.h> 8 9 int main() 10 { 11 int fd=open("./log",O_CREAT|O_RDWR,0644); 12 if(fd<0) 13 { 14 perror("open"); 15 exit(1); 16 } 17 close(1); //必須關(guān)閉要重定向的文件描述符 18 int newfd=dup(fd); 19 if(newfd <0) 20 { 21 perror("dup"); 22 exit(2); 23 }
24 char buf[1024];
25
26 while(1)
27 {
28 memset(buf,'\0',sizeof(buf));
29 fgets(buf,sizeof(buf),stdin);
30 if((strncmp("quit",buf,4))==0)
31 {
32 break;
33 }
34 printf("%s\n",buf);
35 //printf("hello world\n");
36 fflush(stdout);
37 }
38 close(newfd);
39
40 return 0;
41 }
輸入內(nèi)容:
重定向到log文件中內(nèi)容
int dup2(int oldfd,int newfd)
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<fcntl.h> 5 #include<string.h> 6 #include<errno.h> 7 #include<sys/stat.h> 8 9 int main() 10 { 11 int fd=open("./log",O_CREAT|O_RDWR,0644); 12 if(fd<0) 13 { 14 perror("open"); 15 exit(1); 16 } 17 close(1); //可以不必關(guān)閉1號文件描述符 18 int newfd=dup2(fd,1); 19 if(newfd <0) 20 { 21 perror("dup"); 22 exit(2); 23 }
24 char buf[1024]; 25 while(1) 26 { 27 memset(buf,'\0',sizeof(buf)); 28 fgets(buf,sizeof(buf),stdin); 29 if((strncmp("quit",buf,4))==0) 30 { 31 break; 32 } 33 printf("%s",buf); 34 //printf("hello world\n"); 35 fflush(stdout); 36 } 37 close(newfd); 38 39 return 0; 40 } 41
輸入內(nèi)容:
log文件中內(nèi)容:
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。