悬赏高分!分数决不平分!是linux下多进程跟信号问题!在线等!
下面的代码所作的操作是这样的,主进程fork一个工作进程出来,然后主进程往管道里面写一个字符串,然后给工作进程发送一个信号通知它去管道里面读取,然后工作进程去读取某个本地的文本文件,然后输出显示读取了百分之几。。。代码有详细注释,问题在代码的下面! 代码如下:
- C/C++ code
#include<unistd.h>#include<sys/types.h>#include<signal.h>#include<errno.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAIN_PROCESS_WRITE 40#define WORK_PROCESS_WRITE 41#define FILE_PATH "./file.txt"void sigMainToWork(int iSig, siginfo_t *info, void * nothing);void sigWorkToMain(int iSig, siginfo_t *info, void *nothing);void spitString(char acTarget[], char acStart[], char acLength[]);void mySleep();struct allFifo{ //两条管道读写文件描述符 int myFifo1[2]; int myFifo2[2];};void main(){ struct allFifo *fifo = (struct allFifo *)malloc(sizeof(struct allFifo)); int workProcessPid = 0; char acBuf[100] = {0}; //配置信号属性结构体 struct sigaction myActionMain; struct sigaction myActionWork; //信号处理函数所带参数联合体 union sigval myVal; //注册两条管道以便通信 pipe(fifo->myFifo1); pipe(fifo->myFifo2); // myActionWork.sa_sigaction = sigMainToWork; myActionWork.sa_flags = SA_SIGINFO; myActionMain.sa_sigaction = sigWorkToMain; myActionMain.sa_flags = SA_SIGINFO; myVal.sival_ptr = (void *)fifo; sigaction(MAIN_PROCESS_WRITE, &myActionWork, NULL); sigaction(WORK_PROCESS_WRITE, &myActionMain, NULL); workProcessPid = fork(); if(0 == workProcessPid) {//子进程// while(1); } else {//父进程 close(fifo->myFifo1[0]); close(fifo->myFifo2[1]); write(fifo->myFifo1[1], "0 1000", sizeof("0 1000")); sigqueue(workProcessPid, MAIN_PROCESS_WRITE, myVal); while(1); }}void sigMainToWork(int iSig, siginfo_t *info, void *nothing){ union sigval myVal; struct allFifo *fifo; FILE * myFile; char acRead[20]; char acStart[10]; char acLength[10]; //读取文件内容的起始位置跟字节数 unsigned int iStart = 0; unsigned int iLength = 0; int iTemp = 0; //获取结构体参数,成员是两条管道的读写文件描述符 fifo = (struct allFifo *)info->si_value.sival_ptr; //从其中一条管道中读取信息, read(fifo->myFifo1[0], acRead, sizeof(acRead)); //解析从管道传过来的信息,其中包含读取文件内容的起始地址和读取的字节数 spitString(acRead, acStart, acLength); //从字符串转换成整型 iStart = strtol(acStart, NULL, 10); iLength = strtol(acLength, NULL, 10); printf("从文件中第 %s 个字符处读取 %s 个字符:\n", acStart, acLength); //打开文件进行读取内容 myFile = fopen(FILE_PATH, "r"); //文件定位到 iStart 处 fseek(myFile, iStart, SEEK_SET); while(1) {//进入循环开始读取文件中的内容 memset(acRead, 0, sizeof(acRead)); fread(acRead, 10, 1, myFile); if(feof(myFile) != 0) {//如果文件指针到了文件尾则退出 break; } //在通过另一条管道写进去 write(fifo->myFifo2[1], acRead, 10); //发送信号通知主进程,内容已经读取并写进管道了 myVal.sival_ptr = info->si_value.sival_ptr; sigqueue(getppid(), WORK_PROCESS_WRITE, myVal); //好像这个延时的函数不起作用,输出打印信息的时候还是很快全部输出,看不到效果 mySleep(); printf("读取中...%%%d\n",iTemp++); }}//主进程收到信号后的处理函数,不作任何操作void sigWorkToMain(int iSig, siginfo_t *info, void *nothing){}//字符串处理函数,把目标字符串处理之后把起始位置存在第二个参数,把读取的字节数存在第三个参数void spitString(char acTarget[], char acStart[], char acLength[]){ int i = 0; int j = 0; for(; acTarget[i] != ' '; i++) { acStart[i] = acTarget[i]; } acStart[i] = '\0'; for(i++; acTarget[i] != '\0'; i++,j++) { acLength[j] = acTarget[i]; } acLength[j] = '\0';}void mySleep(){ unsigned int i = 0; unsigned int j = 0; for(i = 0; i<65500; i++) { for(j = 0; j<2000; j++) { } }}上面的代码问题有两个:就是子进程如果加一个 while(1); 的死循环就什么都打印不出来拉,还有就是工作进程的那个信号处理函数有一个延时函数似乎不起作用。。。。在线等为什么会这样!!!我自己研究了很久了!回答好了另外加分!
[解决办法]
mysleep用sleep代替。
判断read和write的返回值。
我真心懒得看楼主代码了,写的太烂了,
110 while(1)
111 {//进入循环开始读取文件中的内容
112 memset(acRead, 0, sizeof(acRead));
113 fread(acRead, 10, 1, myFile);
114 if(feof(myFile) != 0)
115 {//如果文件指针到了文件尾则退出
116 break;
117 }
118 //在通过另一条管道写进去
119 write(fifo->myFifo2[1], acRead, 10);
120 //发送信号通知主进程,内容已经读取并写进管道了
121 myVal.sival_ptr = info->si_value.sival_ptr;
122 sigqueue(getppid(), WORK_PROCESS_WRITE, myVal);
123
124 //好像这个延时的函数不起作用,输出打印信息的时候还是很快全部输出,看不到效果
125 mySleep();
126 printf("读取中...%%%d\n",iTemp++);
127 }
128
129 }
你看看你这个代码,到底要写多少给父进程?
93
94 //获取结构体参数,成员是两条管道的读写文件描述符
95 fifo = (struct allFifo *)info->si_value.sival_ptr;
96 //从其中一条管道中读取信息,
97 read(fifo->myFifo1[0], acRead, sizeof(acRead));
98 //解析从管道传过来的信息,其中包含读取文件内容的起始地址和读取的字节数
99 spitString(acRead, acStart, acLength);
100 //从字符串转换成整型
101 iStart = strtol(acStart, NULL, 10);
102 iLength = strtol(acLength, NULL, 10);
103
104 printf("从文件中第 %s 个字符处读取 %s 个字
这里也不判断read了多少,万一返回的比你期望的多呢,万一少呢?