赞
踩
我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
并发编程和异步编程是程序员的基本技能,各种高级语言也开发出了一些高级但晦涩的机制(比如C#的await/async)。并发编程主要是指多进程、多线程和交替执行,异步编程则是指多个并发执行任务之间的交互。
目录
并发的几种方式的区别:
任务交互的不同方式:
这几个技术的详细介绍应该很容易找到,我们关心的是如何写出一个套路代码。以下是一个多进程的框架程序,能够起一组子进程并等待所有子进程结束。
首先定义子进程的执行代码的接口:
- class IChildProcess
- {
- public:
- virtual int doChildProcess(long max_process, long i_process) = 0;
- };
纯虚函数doChildProcess是子进程的功能入口,以最大进程数和子进程序号为参数,子进程序号从0开始。按照C语言的习惯这个接口应该加一个void*参数供调用方传入来控制子进程的功能,但是这里写成了虚函数,直接在类里面定义就可以了,这是C++比C方便的地方。
多进程框架:
- int SimpleMultiProcess(IChildProcess * pChild,long max_process, char const* title)
- {
- pChild->isThread = false;
- thelog << "开始执行" << title << " 进程 " << max_process << endi;
- time_t t1 = time(NULL);
- long i_p;
- for (i_p = 0; i_p < max_process; ++i_p)
- {
- pid_t pid = fork();
- if (pid < 0)
- {
- thelog << "fork失败" << ende;
- return __LINE__;
- }
- else if (0 == pid)//子进程
- {
- exit(pChild->doChildProcess(max_process, i_p));//子进程在这里通过exit结束
- }
- }
- int status;
- int ret = 0;
- stringstream msg;
- for (i_p = 0; i_p < max_process; ++i_p)
- {
- pid_t pid = waitpid(-1, &status, 0);//等待任何一个子进程结束,原则上这个循环写法有问题,如果程序还有其它地方创建子进程则这里程序行为就不符合预期
- if (-1 == pid)
- {
- thelog << "waitpid 出错 " << strerror(errno) << ende;
- return __LINE__;
- }
- else
- {
- if (WIFEXITED(status))
- {
- int tmpret = (0xFF00 & status) / 256;//WEXITSTATUS宏无法识别
- if (0 != tmpret)
- {
- msg << "进程 " << pid << " 出错,返回值 " << tmpret << " 状态码 " << status << endl;
- ret = tmpret;
- }
- }
- else
- {
- ret = 2;
- msg << "进程 " << pid << " 异常,状态码 " << status << endl;
- }
- }
- }
- int timespan = time(NULL) - t1;
- if (msg.str().size() != 0)thelog << msg.str() << ende;
- thelog << "执行" << title << "完成 进程 " << max_process << " 总用时 " << timespan << "/秒" << endi;
-
- return ret;
- }
以执行代码的接口为参数,传入最大进程数,title没什么用,只是用来在日志里显示。
线程和原子大概是C++11最棒的新功能了吧。
为啥以前的线程库都那么复杂啊?
仍然是上面多进程的执行代码的接口:
- class IChildProcess
- {
- public:
- virtual int doChildProcess(long max_process, long i_process) = 0;
- };
框架代码,比多进程简单:
- int SimpleMultiThread(IChildProcess* pChild, long max_thread, char const* title)
- {
- pChild->isThread = true;
- thelog << "开始执行" << title << " 线程 " << max_thread << endi;
- time_t t1 = time(NULL);
- long i_p;
- vector<thread *> threads;
- for (i_p = 0; i_p < max_thread; ++i_p)
- {
- threads.push_back(new thread(doChildThread, pChild, max_thread, i_p));
- }
- for (auto & v:threads)
- {
- v->join();
- }
- int timespan = time(NULL) - t1;
- thelog << "执行" << title << "完成 线程 " << max_thread << " 总用时 " << timespan << "/秒" << endi;
-
- return 0;
- }
这个代码基本就是一目了然了。当然了,多线程最大困难在于安全地交互。
(这里是结束)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。