进程,线程,多线程

来源:互联网 发布:淘宝上怎么搜迷你钢弩 编辑:程序博客网 时间:2024/06/05 16:58

进程,线程,多线程

进程与线程:

进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位.     【占用资源的最小单元】

线程:它是比进程更小的能独立运行的基本单位.是进程的一个实体,CPU调度和分派的基本单位。它只拥有运行中必不可少的资源(如程序计数器,一组寄存器和栈),但它可与同属一个进程的其他的线程共享进程所拥有的全部资源.            【调度的单位】  

关系:

1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

2)一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。进程之间也可以并发执行.

3)资源分配给进程,同一进程的所有线程共享该进程的所有资源。

4)处理机分给线程,即真正在处理机上运行的是线程。

5)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

区别:

(1)  拥有资源和调度:进程是拥有资源的独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。线程是指进程内的一个执行单元,是调度和分配的基本单位,

(2)  通信:线程之间的通信比较方便。统一进程下的线程共享数据(比如全局变量,静态变量),通过这些数据来通信,快捷方便,但要处理好这些访问的同步与互斥。而进程之间的通信只能通过进程通信的方式进行(如管道,信号,消息队列,共享内存,信号量,套接字)。

(3)  执行:每个独立的线程有自己的一个程序入口,顺序执行序列和程序的出口,但是不能独立执行,必须依附与程序之中,由应用程序提供多个线程的并发控制。

(4)  系统开销:进程有独立的地址空间,在创建或撤消进程时,系统都要为之分配和回收资源,导致开销明显大。运行一个进程中的线程,共享大部分数据,使用相同的地址空间,因此启动一个线程,切换一个线程远比进程操作要快,花费也要小得多。

(5)  健壮性:多进程的程序要比多线程的程序健壮。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。而线程只是一个进程中的不同执行路径,有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。

线程安全:

   多线程的程序运行结果是可预期的,而且与单线程的程序运行结果一样。

 

线程状态:

就绪、运行、阻塞、挂起阻塞、挂起就绪

 

多线程:

1.    多线程互斥与同步有几种实现方法?都是什么?

临界区(CS:critical section)、互斥量(Mutex);事件(Event)、信号量(semaphores)。

a.    临界区(同一个进程内,实现互斥): 在任意时刻只允许一个线程对共享资源进行访问,其他的被挂起,直到临界区被释放。【多线程的串行化,速度快,适合控制数据访问】

b.    互斥量(可以跨进程,实现互斥):只有拥有互斥对象(只有一个)的线程才具有访问资源的权限,当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。【为协调对一个共享资源的单独访问而设计】

###  临界区 VS 互斥量 :

   两者都可以用于同一进程中不同子线程对资源的互斥访问。互斥量可以很好的解决由于线程意外终止资源无法释放的问题。互斥量是内核对象,可以命名,也就是说它可以跨进程使用,所以创建互斥量需要的资源更多。在进程内部,使用临界区会更快。

c.    事件(实现同步,可以跨进程):用来通知线程有一些事件已发生,从而启动后继任务的开始。

d.    信号量(主要是实现同步,可以跨进程): 它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。【为控制一个具有有限数量用户资源而设计】

 

线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。

用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。

 

2.    C++中多线程实现方法:

C++ 11新特性中,可以使用std::thread来创建线程。Windows系统提供了相关API,我们可以使用他们来进行多线程编程。

例子

http://www.cnblogs.com/codingmengmeng/p/5913068.html

线程随机交替运行,运行时间不一样,可能主线程运行完之后将所占资源都释放掉了,使得子线程还没有运行完。   【可用sleep()

注意进程之间会被打断。如:

cout << "Main Thread Display!" <<endl;改成cout << "Main ThreadDisplay!\n";

【用互斥量(Mutex)来进行线程同步,允许一个线程拥有对共享资源的独占。】

 

3.    多线程同步和互斥有何异同,在什么情况下分别使用他们?举例说明

同步,指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。

互斥,指对于共享的进程系统资源,在各单个线程访问时的排它性。线程互斥可以看成是一种特殊的线程同步。”不能同时访问,是个顺序问题“。

举例,设有一个全局变量global,为了保证线程安全,我们规定只有当主线程修改了global之后下一个子线程才能访问global,这就需要同步主线程与子线程,可用关键段实现。当一个子线程访问global的时候另一个线程不能访问global,那么就需要互斥。

 

4.    编程练习

 

参考:

http://blog.csdn.net/yaosiming2011/article/details/44280797

https://www.cnblogs.com/wuchanming/p/3992395.html?utm_source=tuicool&utm_medium=referral

http://www.cnblogs.com/xilentz/archive/2012/11/13/2767317.html

 

原创粉丝点击