进程与线程:
进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位. 【占用资源的最小单元】
线程:它是比进程更小的能独立运行的基本单位. 是进程的一个实体,是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,我们可以使用他们来进行多线程编程。
例子:c 多线程编程实例
线程随机交替运行,运行时间不一样,可能主线程运行完之后将所占资源都释放掉了,使得子线程还没有运行完。 【可用sleep()】
注意进程之间会被打断。如:
cout << "main thread display!" <
【用互斥量(mutex)来进行线程同步,允许一个线程拥有对共享资源的独占。】
3. 多线程同步和互斥有何异同,在什么情况下分别使用他们?举例说明
同步,指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。
互斥,指对于共享的进程系统资源,在各单个线程访问时的排它性。线程互斥可以看成是一种特殊的线程同步。”不能同时访问,是个顺序问题“。
举例,设有一个全局变量global,为了保证线程安全,我们规定只有当主线程修改了global之后下一个子线程才能访问global,这就需要同步主线程与子线程,可用关键段实现。当一个子线程访问global的时候另一个线程不能访问global,那么就需要互斥。