进程间的匿名通信(匿名管道)

管道原理

在这里插入图片描述

int pipe(int pipefd[2]);

  1. 父进程与子进程的读写是有一定顺序的,当父进程没写入数据时,子进程会在read处等待,所以,父进程写入后,子进程read才会读取数据。
  2. 当父进程关闭写入的文件描述符,子进程read会接收到信号,读到的字符数为0,依据这个判断结束

简单使用

int main()
{
    int pipefd[2];

    pipe(pipefd);

    pid_t id =fork();

    if(id==0)
    {
        //子进程 ,进行读
        close(pipefd[1]);
        #define NUM 1024
        char buf[NUM];
        while(1)
        {
            memset(buf,0,NUM);
            //子进程在等待父进程write
            ssize_t s =read(pipefd[0],buf,sizeof(buf)-1);
            if(s>0)
            {
                cout<<buf<<endl;
            }
            else if(s==0)
            {
                cout << "父进程写完了,我也退出啦" << endl;
                break;
            }
            
        }
        close(pipefd[0]);
        exit(0);

    }
    else if (id>0)
    {
        //父进程
        close(pipefd[0]);
        #define NUM 1024

        char ch[NUM]="我是父进程,我在给子进程通过管道传输数据";
        for(int i=0;i<5;i++)
        {
            write(pipefd[1],ch,strlen(ch));
            sleep(1);
        }

        close(pipefd[1]);

        id_t res = waitpid(id, nullptr, 0);
        if(res > 0)
        {
            cout << "等待子进程成功" << endl;
        }
    }
    else
    {
        //错误
        cerr<<"创建进程失败\n";
    }

    return 0;
}

父进程控制子进程

typedef void (*functor)();

void fun1()
{
    cout<<"我在写日志"<<endl;
}

void fun2()
{
    cout<<"我在处理文件"<<endl;
}

void fun3()
{
    cout<<"我在处理数据"<<endl;
}

vector<functor> functors;

void loadFunctor()
{
    functors.push_back(fun1);
    functors.push_back(fun2);
    functors.push_back(fun3);
}
int main()
{
    loadFunctor();

    int pipefd[2];

    //创建管道
    pipe(pipefd);

    pid_t id =fork();

    if(id==0)
    {
        //子进程,读
        close(pipefd[1]);
        int missionType =0;
        while(1)
        {
            ssize_t s=read(pipefd[0],&missionType,4);
            if(s==0)
            {
                cout<<"父进程不再分派任务"<<endl;
                break;
            }
            else if(s>0)
            {
                work(missionType);
            }
        }
        close(pipefd[0]);
        exit(0);
    }

    //父进程
    
    close(pipefd[0]);
    int mission=0;
    srand( (size_t)time(0));
    for(int i=0;i<5;i++)
    {
        sleep(2);
        mission=rand()%functors.size();
        write(pipefd[1],&mission,4);
    }

    close(pipefd[1]);
    id_t res = waitpid(id,nullptr,0);
    if(res>0)
    {
        cout<<"父进程等待成功"<<endl;
    }
    return 0;
}

进程池

typedef void (*functor)();
// int: 进程pid, int: 该进程对应的管道写端fd

typedef pair<int, int> elem;

void fun1()
{
    cout<<"我在写日志"<<endl;
}

void fun2()
{
    cout<<"我在处理文件"<<endl;
}

void fun3()
{
    cout<<"我在处理数据"<<endl;
}

vector<functor> functors;

void loadFunctor()
{
    functors.push_back(fun1);
    functors.push_back(fun2);
    functors.push_back(fun3);
}

void work(int pipefd)
{
    while(1)
    {
        int missionType;
        ssize_t s = read(pipefd,&missionType,4);
        if(s>0)
        {
            functors[missionType]();
        }
        else  if(s==0)
        {
            break;
        }
    }
}

void sendTask(const vector<elem>& process)
{
    srand((size_t) time(0));
    for(int i=0;i<5;i++)
    {
        sleep(1);
        //选择哪个子进程
        int pick = rand()%5;

        //选择执行什么
        int task= rand()%3;
        cout<<"给编号为:"<<pick<<"的进程派发任务"<<endl;
        write(process[pick].second,&task,4);
    }
}

// int32_t: 进程pid, int32_t: 该进程对应的管道写端fd
int main()
{
    loadFunctor();
    vector<elem> process;
    int pipefd[2];
    for(int i=0;i<5;i++)
    {
        pipe(pipefd);
        pid_t id = fork();
        if(id==0)
        {
            //子进程
            close(pipefd[1]);
            work(pipefd[0]);

            close(pipefd[0]);
            cout<<"我是子进程:"<< getpid()<<endl;
            exit(0);
        }
            //父进程做的:
            close(pipefd[0]);
            elem e(id,pipefd[1]);
            process.push_back(e);
    }

    //父进程,派发任务
    sendTask(process);
    
    for(int i=0;i<5;i++)
    {
        close(process[i].second);
        if(waitpid(process[i].first,nullptr,WNOHANG)>0)
        {
            cout<<"pid :"<<process[i].first<<"等待成功"<<endl;
        }

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值