日期:2014-05-16  浏览次数:20713 次

悬赏高分!分数决不平分!是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++)
        {

        }
    }
}






上面的代