C++学习笔记--多进程

原创 2016年08月30日 20:54:10

C++并发编程有多线程和多进程两种方式,本文主要讲述进程和线程的概念,以及两者的区别,然后简单讲述如何使用Linux API进行多进程编程,多线程编程使用C++标准库即可实现,请参考C++学习笔记–多线程

1 进程概念

进程是程序的一次动态执行过程。程序本身只是指令的集合,进程才是程序的真正运行,用户运行程序就产生了进程,用户关闭程序就结束了进程。一个程序可以产生多个进程,但一个进程只能由一个程序产生。进程有5种生命周期状态:创建、就绪、运行、阻塞、退出,下图表示了5种状态之间的关系。
进程的5种状态
与上面的5种状态不同,在Linux中使用top命令查看进程也有5种状态,但它是以不同的角度来描述进程状态:
R:运行状态,正在运行或在运行队列中等待
S:可中断(自愿)的睡眠状态,在等待某事件发生才可唤醒。如网页服务器的httpd进程,在客户端(浏览器)发出请求之前,服务器无事可做,选择睡眠。是程序角度的睡眠,程序本身控制自己的运行状态
D:不可中断(非自愿)的睡眠状态,有时两个进程试图同时访问同一系统资源,例如一个进程试图从磁盘数据块上读取信息,而另一个进程正在向该数据块写入信息。在这种情况下,内核迫使进程进入非自愿睡眠状态,该进程并没有自愿选择睡眠。当资源被释放时,内核会唤醒进程并将其设置为可运行状态。虽然进程断的进入和离开非自愿睡眠,但是它们通常不会在该状态停留太久。因此,除了在高负荷的系统上,用户通常看不到处于非自愿睡眠状态的进程。
T:停止或跟踪状态,进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行
Z:僵死状态,子进程先于父进程退出,同时父进程又没有调用wait()或waitpid(),则该子进程将成为僵尸进程。为了防止产生僵尸进程,在fork子进程之后我们都要在父进程wait它们

2 线程概念

早期的计算机系统只有进程,没有线程,后来发现进程切换的开销有点大,于是产生了线程(也称轻量级进程),线程切换比进程切换的开销要小很多。线程是程序执行中一个单一的顺序控制流,是程序执行流的最小单元,是处理器调度和分派的基本单位,是进程中代码的不同执行路线,一个进程可以有多个线程。
现在的处理器一般是双核或四核的,每个处理核心对应一个内核线程,但是我们经常看到双核心四线程或四核心八线程的描述,这其实是采用了超线程技术将一个物理处理核心模拟成两个逻辑处理核心,对应两个内核线程,所以采用了超线程技术的CPU在操作系统中看到的CPU数量是实际物理CPU数量的两倍。这里讲到了内核线程,内核线程(Kernel Thread, KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。而用户程序一般是创建用户线程,然后用户线程调用内核线程,在现在流行的操作系统中,用户线程和内核线程是多对多的映射调用关系。

3 进程、线程的区别与联系

一个程序至少产生一个进程,一个进程至少产生一个线程,线程再映射到内核线程,在处理器上完成计算任务。
进程与线程的区别,关键就在于它们独立拥有的资源不同,因此就体现出了不同的特性,主要有以下几方面的不同:
(1)资源
进程作为除CPU以外系统资源的分配单位,每个进程都拥有独立的地址空间和资源,因此一个进程崩溃不会引起其他进程的运行,就好像是不同程序创建的不同进程互不影响一样;
线程作为CPU的分配单位,是被系统独立调度和分派的基本单位,本身仅拥有CPU中的寄存器和线程函数调用需要的堆栈区这一点点资源,其他资源如代码、公有数据、文件描述符等都是与其他线程共享的进程资源,所以一个线程崩溃,整个进程都崩溃。
(2)系统开销
由于每个进程都拥有独立的地址空间和资源,因此进程的创建和撤销都需要资源的分配和回收,系统开销大;
每个线程仅仅拥有一点必不可少的资源,所以创建和撤销都很快。
(3)通信方式
进程之间主要有6种通信方式:管道、信号、消息队列、共享内存、信号量、socket;
线程之间主要有3种通信方式:锁机制(包括互斥锁、条件变量、读写锁)、信号量机制、信号机制。
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
通信方式的内容写得不够详细,后续再补充,下面这些是暂时记录的内容:

信号量:一个初始值为N的信号量允许N个线程并发访问。线程访问资源时首先获取信号量锁,进行如下操作:
1. 将信号量的值减1;
2. 如果信号量的值小于0,则进入等待状态,否则继续执行;
访问资源结束之后,线程释放信号量锁,进行如下操作:
1. 将信号量的值加1;
2. 如果信号量的值小于1(等于0),唤醒一个等待中的线程;
同步:多个事件一起开始,一起结束(一刀切);
异步:多个事件各走各的,完成了通知一下控制中心;
阻塞:所申请资源被占用、启动IO传输未完成,必须等待资源或事件完成才可以进行下一步称为阻塞;
挂起:挂起是主动的,一般需要用挂起函数进行操作,若没有resume的动作,则此任务一直不会ready,而阻塞是因为资源被其他任务抢占而处于休眠态。

4 Linux下C++多进程编程实现

待补充

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++关闭和创建进程

在VC程序中如何结束系统正在运行的其他进程(该进程必须有窗口界面),其实很简单,按如下步骤进行即可:    1.取得进程的句柄(利用FindWindow函数得到);    2.获取进程ID号(用Get...
  • yuri99
  • yuri99
  • 2010年05月21日 16:10
  • 7666

C++创建一个新的进程

STARTUPINFO用于指定新进程的主窗口特性的一个结构。 PROCESS_INFORMATION在创建进程时相关的数据结构之一,该结构返回有关新进程及其主线程的信息。...
  • hk627989388
  • hk627989388
  • 2016年11月23日 19:31
  • 2852

linux下的C\C++多进程多线程编程简易例子

多进程编程   #include #include #include int main() { pid_t child_pid; /* 创建一个子进程 */ ch...
  • FENGQIYUNRAN
  • FENGQIYUNRAN
  • 2015年04月19日 17:01
  • 4998

编程思想之多线程与多进程(4)——C++中的多线程

《编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程》一文详细讲述了线程、进程的关系及在操作系统中的表现,《编程思想之多线程与多进程(2)——线程优先级与线程安全》一文讲了线程安全(各种...
  • luoweifu
  • luoweifu
  • 2015年07月10日 21:48
  • 16851

【C/C++】多进程:子进程的创建fork()

文章结构:进程结构fork函数示例代码frok使用场景进程结构  Linux下一个进程在内存里有三部分的数据,就是”代码段”、”堆栈段”和”数据段”。接触过汇编语言的人了解,一般的CPU都有上述三种段...
  • sodino
  • sodino
  • 2015年04月20日 08:50
  • 18590

【C/C++】多进程:父进程监听子进程状态 wait()的使用

文章结构:wait能力介绍wait()函数讲解示例代码及操作演示wait能力介绍  在上一篇【C/C++】多进程:子进程的创建fork()中演示了子进程的创建。  创建子进程后,父进程具有监听子进程的...
  • sodino
  • sodino
  • 2015年04月20日 08:53
  • 9231

用C++实现一个多进程回显服务器

用C++实现一个多进程回显服务器       本案例将用多进程实现一个基于Linux使用C++实现的C/S网络程序:客户端从终端输入,然后借助服务端回显。进而观察TCP的状态转换图,发现多进程网络编程...
  • ac_dao_di
  • ac_dao_di
  • 2016年11月28日 23:08
  • 1480

Linux下C++多进程应用开发

转自:http://blog.csdn.net/wangfengwf/article/details/11581487 =====================================...
  • u012398362
  • u012398362
  • 2016年02月18日 15:31
  • 965

【C/C++】多进程:僵尸进程

一个僵尸进程产生的过程是:父进程调用fork创建子进程后,子进程运行至其终止。进程终止后有些信息对于父进程和内核还是很有用的,例如进程的ID号、进程的退出状态、进程运行的CPU时间等。因此进程运行终止...
  • sodino
  • sodino
  • 2015年04月20日 08:53
  • 2227

Unix/Linux C++应用开发-多进程应用开发

Linux下C++实现并发应用开发首先离不开多进程的支持,本文将会主要介绍Linux系统下进程的基本概念,主要包含Linux系统下进程的基本定义、组成部分、进程的状态以及进程创建等。另外还会根据多进程...
  • wangfengwf
  • wangfengwf
  • 2013年09月11日 21:42
  • 8148
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++学习笔记--多进程
举报原因:
原因补充:

(最多只允许输入30个字)