首页 > 代码库 > Linux_C bc/利用2根管道让2进程通讯

Linux_C bc/利用2根管道让2进程通讯

 1 /* tingbc.c 2  * use two pipe to execute the bc. 3  * one pipe: todc[2] , another: fromdc[2] 4  * child thread to do dc, parent do UI 5  */ 6  7 #include <stdio.h> 8 #include <unistd.h> 9 #include <string.h>10 #define oops(x, n) {perror(x); exit(n);}11 12 void be_dc(int todc[], int fromdc[]);13 void be_bc(int todc[], int fromdc[]);14 int main(void) {15   int todc[2], fromdc[2], pid;16   if(pipe(todc)==-1 || pipe(fromdc)==-1)17     oops("pipe", 2);18   if((pid=fork()) == -1)19     oops("fork" ,3);20   if(pid==0) {21     be_dc(todc, fromdc);//child do dc22   }else{23     be_bc(todc, fromdc);//parent do UI24     wait(NULL);25   }26   return 0;27 }28 29 void be_dc(int todc[], int fromdc[]){30   //will do dc() , change the stdin to todc[1], change the stdout to fromdc[0]31   close(todc[1]);32   close(fromdc[0]);33   if(dup2(todc[0], 0)==-1)34     oops("could not redirect the stdin", 4);35   if(dup2(fromdc[1], 1)==-1)36     oops("could not redirct the stdout", 5);37   close(todc[0]);38   close(fromdc[1]);39   execlp("dc", "dc", "-",NULL);40   oops("exe",1);41 }42 43 void be_bc(int todc[], int fromdc[]){44   //will do bc(), change the stdout to todc[1], and use the fromdc[0] to read the dc‘s result45   char cmdbuf[BUFSIZ];46   int c1, c2;47   char operator;48   FILE *fout, *fread; 49   close(todc[0]);   //donot need to todc out50   close(fromdc[1]);  //donot need to fromdc in  51   52   fout=fdopen(todc[1],"w");  //write the todc[1]53   fread=fdopen(fromdc[0],"r" );     //read the dc‘s result from fromdc[0]54   55   while((printf("tinybc: ")) && (fgets(cmdbuf, BUFSIZ, stdin )!=-1)) {56     if( sscanf(cmdbuf, "%d %c %d", &c1,&operator,&c2) !=3) {57       printf("syntax error.\n");58       continue;59     }60     printf("2u cin is %d %c %d\n", c1,operator,c2);61     if(fprintf(fout, "%d\n%d\n%c\np\n", c1,c2,operator) == EOF)//在这里有问题,c1总是读不进去,一直是0.62       oops("fprintf", 6);63     64     fflush(fout);65     if(fgets(cmdbuf, BUFSIZ, fread)==NULL)66       break;67     printf("%d %c %d = %s", c1, operator, c2, cmdbuf);68   }69   close(todc[0]);70   close(fromdc[1]);71 }

这里,在2个pipe使用时,要分清楚pipe[0],pipe[1]哪一个是读出哪一个是写入。

同时这里用到了sscanf函数。

/**********************************************************************************************/

sscanf(格式化字符串输入)
相关函数 scanf,fscanf
表头文件 #include<stdio.h>
定义函数 int sscanf (const char *str,const char * format,........);
函数说明 sscanf()会将参数 str 的字符串根据参数 format 字符串来转换并格
式化数据。格式转换形式请参考 scanf()
。转换后的结果存于对应
的参数内。
返回值
成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。
范例
#include<stdio.h>
main()
{
int i;
unsigned int j;
char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;
char s[5];
sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s);
printf(“%d %d %s\n”,i,j,s);
}

 

/***************************************************************************************/

fdopen函数

fdopen函数与fopen类是,返回一个FILE*类型值,不同的是此函数以文件描述符而非文件作为参数。

使用fopen的时候,将文件名作为参数传给它。fopen可以打开设备文件也可以打开常规的磁盘文件。如只知道文件描述符而不清楚文件名的时候可以使用fdopen。

使用fdopen使得对远端的进程的处理就如同处理常规文件一样

Linux_C bc/利用2根管道让2进程通讯