#include <iostream>
#include <vector>
#include <unistd.h>
#include <cassert>
#include <sys/types.h>
#include <string>
#include <sys/wait.h>
// using namespace std;
#include "Tash.hpp"
class channel//封装文件下标fd
{
public:
channel(int cd, pid_t id) : ctrlfd(cd), workid(id)
{
}
public:
int ctrlfd;
pid_t workid;
std::string name;
};
void work()//工作函数
{
while (true)
{
int code = 0;
ssize_t n = read(0, &code, sizeof code);//取出任务码
if (n == 4)
{
if (!init.Checkcode(code))
{
continue;
}
init.Runtask(code);//运行
}
else if (n == 0)
{
break;
}
else
{
}
}
std::cout << "chird quit" << std::endl;
}
void creat(std::vector<channel> *c)
{
std::vector<int> old;//存储主进程已经打开的pipe文件
for (size_t i = 0; i < 5; i++)
{
int pipefd[2] = {0};//使用匿名管道完成通信
int n = pipe(pipefd);
assert(n == 0);
(void)n;
std::cout<<"creat"<<std::endl;
int id = fork();
assert(id != -1);
if (id == 0)
{
if (!old.empty())//子进程关闭主进程已经打开的pipe文件
{
for (const auto fd : old)
{
close(fd);
}
}
close(pipefd[1]);
dup2(pipefd[0], 0);
work();
exit(0);
}
close(pipefd[0]);
c->push_back(channel(pipefd[1], id));
old.push_back(pipefd[1]);
}
}
void sendCommand(std::vector<channel> c, int flag, int num=0)
{
int pos = 0;
while (true)
{
int command = init.SelectTask();
const auto &tem = c[pos++];
pos %= c.size();
std::cout << "send command " << init.Todesc(command) << "[" << command << "]"
<< " in "
<< tem.name << " worker is : " << tem.workid << std::endl;
write(tem.ctrlfd, &command, sizeof command);//将任务写进对应的pipe文件
if (!flag)//判断是否一直使用
{
num--;
if (num == 0)
break;
}
sleep(1);
}
std::cout<<"SendCommand done..." <<std::endl;
}
void Releasechannel(std::vector<channel>c)
{
for( auto i: c)
{
close(i.ctrlfd);
waitpid(i.workid,nullptr,0);
}
}
int main()
{
std::vector<channel> channels;
creat(&channels);
const bool g_always_loop = true;
sendCommand(channels, g_always_loop);
//sendCommand(channels, !g_always_loop, 10);
Releasechannel(channels);
return 0;
}
任务类
#pragma once
#include <iostream>
#include <unistd.h>
#include <functional>
#include <vector>
#include <ctime>
typedef std::function<void()> task;
void Download()
{
std::cout << "我是一个下载任务"
<< " 处理者: " << getpid() << std::endl;
}
void PrintLog()
{
std::cout << "我是一个打印日志的任务"
<< " 处理者: " << getpid() << std::endl;
}
void PushVideoStream()
{
std::cout << "这是一个推送视频流的任务"
<< " 处理者: " << getpid() << std::endl;
}
class Init
{
public:
const static int g_download_code=0;
const static int g_print_log_code=1;
const static int g_push_video_stream_code=2;
std::vector<task>tasks;
public:
Init()
{
tasks.push_back(Download);
tasks.push_back(PrintLog);
tasks.push_back(PushVideoStream);
srand(time(nullptr)^getpid());
}
bool Checkcode(int code)
{
if(code>=0&&code<tasks.size())
{
return true;
}
else
{
return false;
}
}
void Runtask(int code)
{
return tasks[code]();
}
int SelectTask()
{
return rand()%tasks.size();
}
std::string Todesc(int code)
{
switch (code)
{
case g_download_code :
return "Download";
case g_print_log_code :
return "PrintLog";
case g_push_video_stream_code :
return "PushVideoStream";
default:
return "Unknow";
}
}
};
Init init;