头文件:

#include <iostream>
#include <unistd.h>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctime>
#define makeSeed() srand((unsigned long)time(nullptr) ^ getpid() ^ 0xa33b12 ^ rand() % 1234);
#define PROCESS_NUM 5
typedef void (*func_t)();

main.cc

void example1Task()
{
std::cout << getpid() << ":Task_1\n"
<< std::endl;
sleep(1);
}
void example2Task()
{
std::cout << getpid() << ":Task_2\n"
<< std::endl;
sleep(1);
}
void example3Task()
{
std::cout << getpid() << ":Task_3\n"
<< std::endl;
sleep(1);
}
void loadTaskFunc(std::vector<func_t> *out)
{
assert(out);
out->push_back(example1Task);
out->push_back(example2Task);
out->push_back(example3Task);
}
class subEp
{
public:
subEp(pid_t subID, int writeFd)
: subID_(subID), writeFd_(writeFd)
{
char nameBuffer[1024];
snprintf(nameBuffer, sizeof nameBuffer, "process-%d[pid(%d)-fd(%d)]", num++, subID_, writeFd_);
name_ = nameBuffer;
}
public:
static int num;
std::string name_;
pid_t subID_;
int writeFd_;
};
int subEp::num = 0;
int recvTask(int readFd)
{
int code = 0;
ssize_t s = read(readFd, &code, sizeof code);
if(s == 4) return code;
else if(s <= 0) return -1;
else return 0;
return code;
}
void sendTask(const subEp &process, int taskNum)
{
std::cout << "send task num: " << taskNum << "send to -> " << process.name_ << std::endl;
int n = write(process.writeFd_, &taskNum, sizeof(taskNum));
assert(n == sizeof(int));
(void)n;
}
void createSubProcess(std::vector<subEp> *subs, std::vector<func_t> &funcMap)
{
std::vector<int> deleteFd;
for (int i = 0; i < PROCESS_NUM; i++)
{
int fds[2];
int n = pipe(fds);
assert(n == 0);
(void)n;
pid_t id = fork();
if (id == 0)
{
for(int i = 0; i < deleteFd.size(); i++) close(deleteFd[i]);
// 子进程
close(fds[1]);
while (true)
{
int commandCode = recvTask(fds[0]);
if (commandCode >= 0 && commandCode < funcMap.size())
funcMap[commandCode]();
else if(commandCode = -1) break;
}
exit(0);
}
close(fds[0]);
subEp sub(id, fds[1]);
subs->push_back(std::move(sub));
deleteFd.push_back(fds[1]);
}
}
void loadBlanceContrl(const std::vector<subEp> &subs, const std::vector<func_t> &funcMap, int count)
{
int processnum = subs.size();
int taskNum = funcMap.size();
bool forever = (count == 0 ? true : false);
while (true)
{
// 选择子进程
int subIdx = rand() % processnum;
// 选择任务
int taskIdx = rand() % taskNum;
// 发送任务
sendTask(subs[subIdx], taskIdx);
sleep(1);
if(!forever)
{
count--;
if(count == 0) break;
}
}
for(int i = 0; i < processnum; i++) close(subs[i].writeFd_);
}
void waitPrecess(std::vector<subEp> process)
{
int processNum = process.size();
for(int i = 0; i < processNum; i++)
{
waitpid(process[i].subID_, nullptr, 0);
std::cout << "wait sub process success...: " << process[i].subID_ << std::endl;
}
}
int main()
{
//建立子进程和通信信道
makeSeed();
std::vector<func_t> funcMap;
loadTaskFunc(&funcMap);
std::vector<subEp> subs;
createSubProcess(&subs, funcMap);
int taskCount = 5;
loadBlanceContrl(subs, funcMap, taskCount);
// 回收子进程信息
waitPrecess(subs);
return 0;
}

“但行好事,莫问前程”