当前位置: 技术问答>linux和unix
悬赏高分!分数决不平分!是linux下多进程跟信号问题!在线等!
来源: 互联网 发布时间:2017-02-23
本文导语: 下面的代码所作的操作是这样的,主进程fork一个工作进程出来,然后主进程往管道里面写一个字符串,然后给工作进程发送一个信号通知它去管道里面读取,然后工作进程去读取某个本地的文本文件,然后输出显示...
下面的代码所作的操作是这样的,主进程fork一个工作进程出来,然后主进程往管道里面写一个字符串,然后给工作进程发送一个信号通知它去管道里面读取,然后工作进程去读取某个本地的文本文件,然后输出显示读取了百分之几。。。代码有详细注释,问题在代码的下面! 代码如下:
#include
#include
#include
#include
#include
#include
#include
#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("读取中...%%%dn",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] = '';
for(i++; acTarget[i] != ''; i++,j++)
{
acLength[j] = acTarget[i];
}
acLength[j] = '';
}
void mySleep()
{
unsigned int i = 0;
unsigned int j = 0;
for(i = 0; isi_value.sival_ptr;
122 sigqueue(getppid(), WORK_PROCESS_WRITE, myVal);
123
124 //好像这个延时的函数不起作用,输出打印信息的时候还是很快全部输出,看不到效果
125 mySleep();
126 printf("读取中...%%%dn",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了多少,万一返回的比你期望的多呢,万一少呢?