程序设计:C++ 多进程、多线程原理和一个多进程、多线程框架

        并发编程和异步编程是程序员的基本技能,各种高级语言也开发出了一些高级但晦涩的机制(比如C#的await/async)。并发编程主要是指多进程、多线程和交替执行,异步编程则是指多个并发执行任务之间的交互。

目录

并发和异步的技术介绍

多进程的基本技术

多进程框架代码

多线程的基本技术(C++11)

多线程框架代码


并发和异步的技术介绍

        并发的几种方式的区别:

  • 多进程 进程之间地址空间隔离,不能共享数据,需要通过IPC、文件、信号等进程间交互机制交互,交互困难但容易调试,程序也比较可靠,一个进程异常不会影响其它进程。
  • 多线程 共享内存地址空间,可以随意访问全部数据,必须正确互斥才能避免数据被破坏。
  • 交替执行 比如await/async,所有后台任务都是在同一个线程里执行的,这依赖一套复杂的接口,比较晦涩。一般采用自定义接口,轮询执行的方式,这要求每个任务都比较小,执行时间可控,比如redis。

        任务交互的不同方式:

  • 内存 速度最快,只适用于多线程,有并发冲突问题。
  • 共享内存 速度最快,适用于多进程,有并发冲突问题,而且不可以动态增长。
  • 信号、信号量 不能携带数据,只能用于控制,用起来费劲
  • SOCKET、管道 可靠,但是和服务器、客户端编程一样,复杂
  • 文件 简单,不用学习新技术,有并发冲突问题

多进程的基本技术

  • fork() 复制进程自身,双返回,在父进程返回子进程的pid,在子进程返回0
  • waitpid() 获取进程状态,等待进程结束
  • WIFEXITED() 判断进程状态码是否表示进程是正常退出
  • 获取返回值 获取返回值的宏兼容性并不好!具体看后面的源代码

        这几个技术的详细介绍应该很容易找到,我们关心的是如何写出一个套路代码。以下是一个多进程的框架程序,能够起一组子进程并等待所有子进程结束。

多进程框架代码

        首先定义子进程的执行代码的接口:

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)

        线程和原子大概是C++11最棒的新功能了吧。

  • std::thread 构造函数直接创建子线程
  • std::thread.join 等待子线程结束,join的意思是“合并”,两个线程变成一个

        为啥以前的线程库都那么复杂啊?

多线程框架代码

        仍然是上面多进程的执行代码的接口:

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;}

        这个代码基本就是一目了然了。当然了,多线程最大困难在于安全地交互。

(这里是结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/133432.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VSCode设置中文语言界面(VScode设置其他语言界面)

一、下载中文插件 二、修改配置 1、使用快捷键 CtrlShiftP 显示出搜索框 2、然后输入 configure display language 3、点击 (中文简体) 需要修改的语言配置 三、重启 四、可能出现的问题 1、如果configure display language已经是中文配置&#xff0c;界面仍是英文 解决&a…

VinsFusion排坑指南

Ubuntu18.04Cere 下载1.14.0版本。Ceres安装方法参考vinsfusion的docker fileOpenCV相关报错 参考 https://wenda.ncnynl.com/article/5CV_LOAD_IMAGE_GRAYSCALE 改成 cv::IMREAD_GRAYSCALE 在三个CMakeLists文件中指定opencv的版本&#xff1a; find_package(OpenCV 3.2.0 REQ…

C++成长之路

看好的发展方向&#xff1a; 证券行业软件开发、AI自动化开发、桌面端工具类开发&#xff0c;云桌面技术 产品框架搭建 MFCDuilbLibcef Qt 技术深入 熟知编译器原理 C11/14等新知识的学习 泛型编程 / 模板编程 设计模式 多线程并发 多进程通讯 各种锁及其优缺点 必看书…

css进阶知识点速览

0前言 零基础部分的博客 1选择器进阶 1.1后代选择器 作用&#xff1a;根据html标签的嵌套关系&#xff0c;选择父元素后代中满足条件的元素 选择器语法&#xff1a;选择器1 选择器2 {css} 结果&#xff1a; 在选择器1所找到标签的后代中 注意&#xff1a; 后代包括&#xf…

python 视频硬字幕去除 内嵌字幕去除工具 vsr

项目简介 开源地址&#xff1a;https://github.com/YaoFANGUK/video-subtitle-remover Video-subtitle-remover (VSR) 是一款基于AI技术&#xff0c;将视频中的硬字幕去除的软件。 主要实现了以下功能&#xff1a; 无损分辨率将视频中的硬字幕去除&#xff0c;生成去除字幕后…

java高级之单元测试、反射

1、Junit测试工具 Test定义测试方法 1.被BeforeClass标记的方法,执行在所有方法之前 2.被AfterCalss标记的方法&#xff0c;执行在所有方法之后 3.被Before标记的方法&#xff0c;执行在每一个Test方法之前 4.被After标记的方法&#xff0c;执行在每一个Test方法之后 public …

Xcode15 framework ‘CoreAudioTypes‘ not found

Xcode15遇见"framework ‘CoreAudioTypes’ not found。" 可尝试移除CoreAudioTypes&#xff0c;添加CoreAudio。 CoreAudio是CoreAudioTypes的套壳。 CoreAudio/CoreAudioTypes.h头文件内容 /*CoreAudio/CoreAudioTypes.h has moved to CoreAudioTypes/CoreAudi…

MFC发送http https以及json解析

域名解析成IP char szWeb[128] "www.baidu.com";struct hostent *pHost NULL;pHost gethostbyname(szWeb);//完成主机名到域名的解析char *IP inet_ntoa(*((struct in_addr *)pHost->h_addr));CString ipStr IP;请求三部曲&#xff1a; 1、CInternetSession…

Java学习路线指南

有很多想自学Java或者转行Java的会有很多疑问&#xff0c;笔者在此进行总结。 有很多想自学Java或者转行Java的会有很多疑问&#xff0c;笔者在此进行总结。 Java岗位多&#xff0c;容易找到工作。Java工资天花板高&#xff0c;比如&#xff1a;Java架构师、Java技术总监。Java…

线上JAVA应用平稳运行一段时间后出现JVM崩溃问题 | 京东云技术团队

一、问题是怎么发现的 系统是一个定时任务系统&#xff0c;需要定时执行业务代码&#xff0c;业务代码主要是访问MYSQL数据库和缓存进行操作&#xff0c;该开始启动&#xff0c;系统日志一切正常&#xff0c;但是运行一段时间到凌晨后&#xff0c;系统就自动崩溃了&#xff0c…

取消elementUI中table的选中状态和勾选状态赋值

一、取消所有选中 1、表格上绑定ref 2、清空用户选中数据 this.$refs.loopRef.clearSelection()二、勾选状态赋值 获取数据&#xff0c;flag为true则是选中状态&#xff0c;并将前面勾选框设为选中状态 this.listData.forEach(item> {if(row.flag1){this.$refs.loopRef.to…

JavaEE平台技术——预备知识(Maven、Docker)

JavaEE平台技术——预备知识&#xff08;Maven、Docker&#xff09; 1. Maven2. Docker 在观看这个之前&#xff0c;大家请查阅前序内容。 &#x1f600;JavaEE的渊源 &#x1f600;&#x1f600;JavaEE平台技术——预备知识&#xff08;Web、Sevlet、Tomcat&#xff09; 1. M…

【漏洞复现】typecho_v1.0-14.10.10_unserialize

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 漏洞利用GetShell 下载链接&#xff1a;https://pan.baidu.com/s/1z0w7ret-uXHMuOZpGYDVlw 提取码&#xff1a;lt7a 首页 漏洞点&#xff1a;/install.php?finish 漏洞利用 …

5+单基因泛癌范文式教学,适合小白学习

今天给同学们分享一篇生信文章“Comprehensive Pan-Cancer Analysis of KIF18A as a Marker for Prognosis and Immunity”&#xff0c;这篇文章发表在Biomolecules期刊上&#xff0c;影响因子为5.5。 结果解读&#xff1a; KIF18A的表达及其在泛癌中的诊断价值 TIMER数据库被…

多模态中各种Fusion方式汇总

多模态中各种Fusion骚操作 大噶好&#xff0c;我是DASOU&#xff1b; 今天继续写多模态系列文章&#xff0c;对多模态感兴趣的可以看我之前的文章&#xff1a; 其实对于多模态来说&#xff0c;主要可以从三个部分去掌握它&#xff1a; 如何获取多模态的表示【learning mult…

【ARFoundation学习笔记】ARFoundation基础(下)

写在前面的话 本系列笔记旨在记录作者在学习Unity中的AR开发过程中需要记录的问题和知识点。难免出现纰漏&#xff0c;更多详细内容请阅读原文。 文章目录 TrackablesTrackableManager可跟踪对象事件管理可跟踪对象 Session管理 Trackables 在AR Foundation中&#xff0c;平面…

GoLong的学习之路(番外)如何使用依赖注入工具:wire

我为什么要直接写番外呢&#xff1f;其原因很简单。项目中会使用&#xff0c;其实在这里大家就可以写一些项目来了。 依赖注入的工具本质思想其实都大差不差。无非控制反转和依赖注入。 文章目录 控制反转为什么需要依赖注入工具 wire的概念提供者&#xff08;provider&#x…

【计算机网络笔记】TCP的拥塞控制机制

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Linux生成随机密码

cat /dev/urandom|tr -dc [:alnum:]|head -c20 生成20位数字字母的随机密码。 /dev/urandom生成随机数&#xff0c;tr -dc [:alnum:] 保留所有数字和字母&#xff0c;head -c20保留前20位。 使用原生的Linux命令生成可以说是极度安全的&#xff0c;也适用于批量用户生成的情…

Linux文件描述符和打开文件之间的关系

简介 文件描述符和打开的文件之间似乎呈现出一一对应的关系。然而&#xff0c;实际并非如此。多个文件描述符指向同一打开文件&#xff0c;这既有可能&#xff0c;也属必要。这些文件描述符可在相同或不同的进程中打开。 要理解具体情况如何&#xff0c;需要查看由内核维护的…