当前位置: 首页 > news >正文

织梦如何做网站地图营销型网站有哪些平台

织梦如何做网站地图,营销型网站有哪些平台,智能建造论文,烟台网站排名优化一、进程池的设计 因为每一次我们要进行进程间通信都需要fork,和操作系统做交互是存在很大成本的,所以我们是不是可以提前fork出几个进程,然后当我们想要使用的时候直接去给他们安排任务,这样就减少了系统调用的次数从而提高了内存…

一、进程池的设计

        因为每一次我们要进行进程间通信都需要fork,和操作系统做交互是存在很大成本的,所以我们是不是可以提前fork出几个进程,然后当我们想要使用的时候直接去给他们安排任务,这样就减少了系统调用的次数从而提高了内存申请速度!!

      父进程和多个子进程建立管道之后, 父进程只需要(1)选择任务 (2)选择进程  

1、 先描述管道

 2、加载任务

 3、初始化进程池

        管道继承下去打开的写端都是3号fd 为了让子进程没有管道的概念,我们直接用dup来将子进程的标准输入改成管道文件,这样可以让子进程没有管道的概念,我们也就可以直接无脑从0号fd读取

 4、子进程完成任务

  5、父进程控制子进程

6、菜单

 7、结束进程

 为什么正着回收不行呢?——>因为子进程会把父进程指向前面管道的写端继承下去

       所以2号继承会有指向1号进程写端的fd 3号继承会有1号和2号进程写端的fd…… 所以到10号的时候就会有9个进程写端的fd    所以第一个子进程被回收的时候,会因为一些子进程的写端没有关闭而造成阻塞!!           ·

解决方案1:倒着回收  

解决方案2:两个循环(先把所有写端关闭了再一起回收)

解决方案3:确保子进程只有一个写端(就是在创建的时候就把指向前面几个进程的写端全部关掉)

8 、负载均衡 

随机数种子轮转    或者是   让进程轮流工作

整体代码:

#pragma once#include <iostream>
#include <vector>typedef void (*task_t)();void task1()
{std::cout << "lol 刷新日志" << std::endl;
}
void task2()
{std::cout << "lol 更新野区,刷新出来野怪" << std::endl;
}
void task3()
{std::cout << "lol 检测软件是否更新,如果需要,就提示用户" << std::endl;
}
void task4()
{std::cout << "lol 用户释放技能,更新用的血量和蓝量" << std::endl;
}void LoadTask(std::vector<task_t> *tasks)
{tasks->push_back(task1);tasks->push_back(task2);tasks->push_back(task3);tasks->push_back(task4);
}

#include "Task.hpp"
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>const int processnum = 10;
std::vector<task_t> tasks;// 先描述
class channel
{
public:channel(int cmdfd, int slaverid, const std::string &processname):_cmdfd(cmdfd), _slaverid(slaverid), _processname(processname){}
public:int _cmdfd;               // 发送任务的文件描述符pid_t _slaverid;          // 子进程的PIDstd::string _processname; // 子进程的名字 -- 方便我们打印日志// int _cmdcnt;
};void slaver()
{// read(0)while(true){int cmdcode = 0;int n = read(0, &cmdcode, sizeof(int)); // 如果父进程不给子进程发送数据呢??阻塞等待!if(n == sizeof(int)){//执行cmdcode对应的任务列表std::cout <<"slaver say@ get a command: "<< getpid() << " : cmdcode: " <<  cmdcode << std::endl;if(cmdcode >= 0 && cmdcode < tasks.size()) tasks[cmdcode]();}if(n == 0) break;}
}
// 输入:const &
// 输出:*
// 输入输出:&
void InitProcessPool(std::vector<channel> *channels)
{// version 2: 确保每一个子进程都只有一个写端std::vector<int> oldfds;for(int i = 0; i < processnum; i++){int pipefd[2]; // 临时空间int n = pipe(pipefd);assert(!n); // 演示就可以(void)n;pid_t id = fork();if(id == 0) // child{std::cout << "child: " << getpid() << " close history fd: ";for(auto fd : oldfds) {std::cout << fd << " ";close(fd);}std::cout << "\n";close(pipefd[1]);dup2(pipefd[0], 0);close(pipefd[0]);slaver();std::cout << "process : " << getpid() << " quit" << std::endl;// slaver(pipefd[0]);exit(0);}// fatherclose(pipefd[0]);// 添加channel字段了std::string name = "process-" + std::to_string(i);channels->push_back(channel(pipefd[1], id, name));oldfds.push_back(pipefd[1]);sleep(1);}
}void Debug(const std::vector<channel> &channels)
{// testfor(const auto &c :channels){std::cout << c._cmdfd << " " << c._slaverid << " " << c._processname << std::endl;}
}void Menu()
{std::cout << "################################################" << std::endl;std::cout << "# 1. 刷新日志             2. 刷新出来野怪        #" << std::endl;std::cout << "# 3. 检测软件是否更新      4. 更新用的血量和蓝量  #" << std::endl;std::cout << "#                         0. 退出               #" << std::endl;std::cout << "#################################################" << std::endl;
}void ctrlSlaver(const std::vector<channel> &channels)
{int which = 0;// int cnt = 5;while(true){int select = 0;Menu();std::cout << "Please Enter@ ";std::cin >> select;if(select <= 0 || select >= 5) break;// select > 0&& select < 5// 1. 选择任务// int cmdcode = rand()%tasks.size();int cmdcode = select - 1;// 2. 选择进程// int processpos = rand()%channels.size();std::cout << "father say: " << " cmdcode: " <<cmdcode << " already sendto " << channels[which]._slaverid << " process name: " << channels[which]._processname << std::endl;// 3. 发送任务write(channels[which]._cmdfd, &cmdcode, sizeof(cmdcode));which++;which %= channels.size();// cnt--;// sleep(1);}
}void QuitProcess(const std::vector<channel> &channels)
{for(const auto &c : channels){close(c._cmdfd);waitpid(c._slaverid, nullptr, 0);}// version1 // int last = channels.size()-1;// for(int i = last; i >= 0; i--)// {//     close(channels[i]._cmdfd);//     waitpid(channels[i]._slaverid, nullptr, 0);// }// for(const auto &c : channels) close(c._cmdfd);// // sleep(5);// for(const auto &c : channels) waitpid(c._slaverid, nullptr, 0);// // sleep(5);
}
int main()
{LoadTask(&tasks);srand(time(nullptr)^getpid()^1023); // 种一个随机数种子// 在组织std::vector<channel> channels;// 1. 初始化 --- bug?? -- 找一下这个问题在哪里?然后提出一些解决方案!InitProcessPool(&channels);// Debug(channels);// 2. 开始控制子进程ctrlSlaver(channels);// 3. 清理收尾QuitProcess(channels);return 0;
}

二、日志的设计

1、什么是日志

日志的时间、日志的等级、日志的内容、文章的名称和行号 

帮助我们能够看到一些代码运行过程中的重要信息。 

 2、设置等级和写日志的方式

     因为我们的日志信息可能会需要各种类型   比如%d %s……  所以必须用到可变参数。且格式化为字符串。

     且日志一般情况下是写到文件里的 ,也有可能要按照等级去分文件,因此

 

3、可变参数列表的解析举例

4、日志信息的前半部分(时间)

time是获取一个时间戳  

gettimeofday获取当天的时间(tv是输出型参数)

settimeofday设置当天的时间 (tv是输入型参数)

 localtime 把time类型的返回值传过来  转化成tm结构返回 (有具体的时间信息)

leftbuffer是左半部分的时间信息(可以用格式化,snprintf), rightbuffer是右半部分的日志信息(可变参数 vsnprintf)。 

 可以用运算符重载美化一下,这样调用的时候就更方便

 5、想办法把文件打包

 

#pragma once#include <iostream>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>#define SIZE 1024#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4#define Screen 1
#define Onefile 2
#define Classfile 3#define LogFile "log.txt"class Log
{
public:Log(){printMethod = Screen;path = "./log/";}void Enable(int method){printMethod = method;}std::string levelToString(int level){switch (level){case Info:return "Info";case Debug:return "Debug";case Warning:return "Warning";case Error:return "Error";case Fatal:return "Fatal";default:return "None";}}// void logmessage(int level, const char *format, ...)// {//     time_t t = time(nullptr);//     struct tm *ctime = localtime(&t);//     char leftbuffer[SIZE];//     snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),//              ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,//              ctime->tm_hour, ctime->tm_min, ctime->tm_sec);//     // va_list s;//     // va_start(s, format);//     char rightbuffer[SIZE];//     vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);//     // va_end(s);//     // 格式:默认部分+自定义部分//     char logtxt[SIZE * 2];//     snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);//     // printf("%s", logtxt); // 暂时打印//     printLog(level, logtxt);// }void printLog(int level, const std::string &logtxt){switch (printMethod){case Screen:std::cout << logtxt << std::endl;break;case Onefile:printOneFile(LogFile, logtxt);break;case Classfile:printClassFile(level, logtxt);break;default:break;}}void printOneFile(const std::string &logname, const std::string &logtxt){std::string _logname = path + logname;int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // "log.txt"if (fd < 0)return;write(fd, logtxt.c_str(), logtxt.size());close(fd);}void printClassFile(int level, const std::string &logtxt){std::string filename = LogFile;filename += ".";filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"printOneFile(filename, logtxt);}~Log(){}void operator()(int level, const char *format, ...){time_t t = time(nullptr);struct tm *ctime = localtime(&t);char leftbuffer[SIZE];snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,ctime->tm_hour, ctime->tm_min, ctime->tm_sec);va_list s;va_start(s, format);char rightbuffer[SIZE];vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);va_end(s);// 格式:默认部分+自定义部分char logtxt[SIZE * 2];snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);// printf("%s", logtxt); // 暂时打印printLog(level, logtxt);}private:int printMethod;std::string path;
};// int sum(int n, ...)
// {
//     va_list s; // char*
//     va_start(s, n);//     int sum = 0;
//     while(n)
//     {
//         sum += va_arg(s, int); // printf("hello %d, hello %s, hello %c, hello %d,", 1, "hello", 'c', 123);
//         n--;
//     }//     va_end(s); //s = NULL
//     return sum;
// }

 

http://www.yayakq.cn/news/557645/

相关文章:

  • 医疗科技网站建设网站建设评审会的通知
  • 网站后台维护怎么做优质的做pc端网站
  • 办网站流程赤峰市做网站
  • 2003系统做网站如何制造公司网址
  • 自住房车各项建设部网站女孩做网站合适吗
  • 网站本地环境搭建软件苏州定制型网站建设
  • 什么网站做污水处理药剂的好广告模板制作
  • 桂林旅游网站wordpress标题去重
  • 咨询北京国互网网站建设站酷网官网进入
  • 网上接手袋做是哪一个网站上海外贸公司最新招聘
  • 手表哪个网站做的好建设银行企业网银缴费
  • 乡村旅游网站建设的意义个人持有域名可以做公司网站吗
  • 如何创网站自助网站
  • 男女情感类网站现在网站尺寸
  • 淘宝客推广网站建设设计微信小程序
  • asp.net 网站开发视频2003网站的建设
  • 惠州高端模板建站做集群网站
  • 合肥建设工程招聘信息网站wordpress 数据库函数
  • 网站建设论坛fantodo天津网站建设信息科技有限公司
  • 郑州网站推广哪家效果好口碑营销案例简短
  • 律师网站设计中学生做网站的软件
  • wordpress上传图片路径修改企业网站优化公司有哪些
  • 企业建站公司是干嘛的巩义网站优化技巧
  • 嘉兴网站seo公司广州网站开发网络公司
  • 营销型网站建设区别如何注册网络公司
  • 成都网站制作公司 dedecms网站建设 中企动力板材生态板
  • 深圳做网站哪里最好做网站的服务器有哪些
  • 代做网站app朝阳凌源网站建设
  • 建站网站怎么上传代码网站友情链接怎么样做
  • dedecms生成xml网站地图做产品推广什么网站会比较好