一个进程必须要有至少一个线程,但可以有多个线程。而一个线程只能在一个进程的地址空间内执行。2、资源分配给进程,同一个进程的所有线程共享该进程所有资源。3、CPU分配给线程,即真正在处理器运行的是线程。为了实现同步,执行中的线程需要相互协作,跨进程的线程应使用消息通信方式。
进程是资源分配的基本单位,线程是CPU调度和分派的基本单位
线程是进程的一部分,一个线程只能属于一个进程,一个进程可以有多个线程,但至少有一个线程
每个进程都有独立的代码和数据空间(程序上下文),程序间的切换开销大,线程可看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程间切换开销小
在操作系统中能同时运行多个进程(程序),在同一个进程(程序)中多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)
系统在运行的时候会为每个进程分配不同的内存空间,线程除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源
没有现成的进程可以看做单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,维斯多条线(线程)共同完成
线程是进程的一部分,故线程被称为轻权进程/轻量级进程
进程与线程的关系
1、一个进程可以有多个线程,但至少有一个线程;而一个线程只能在一个进程的地址空间内活动。
2、资源分配给进程,同一个进程的所有线程共享该进程所有资源。
3、CPU分配给线程,即真正在处理器运行的是线程。
4、线程在执行过程中需要协作同步,不同进程的线程间要利用消息通信的办法实现同步。
进程之间哪些可以共享?
线程共享的环境包括:进程代码段、进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)、进程打开的文件描述符、信号的处理器、进程的当前目录和进程用户ID与进程组ID。
进程拥有这许多共性的同时,还拥有自己的个性。有了这些个性,线程才能实现并发性。这些个性包括:
1.线程ID
每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标识线程。
2.寄存器组的值
由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线程切换到另一个线程上时,必须将原有的线程的寄存器集合的状态保存,以便将来该线程在被重新切换到时能得以恢复。
3.线程的堆栈
堆栈是保证线程独立运行所必须的。
线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影响。
4.错误返回码
由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用后设置了errno值,而在该线程还没有处理这个错误,另外一个线程就在此时被调度器投入运行,这样错误值就有可能被修改。
所以,不同的线程应该拥有自己的错误返回码变量。
5.线程的信号屏蔽码
由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自己管理。但所有的线程都共享同样的信号处理器。
6.线程的优先级
由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参数,这个参数就是线程的优先级。
进程间通信的五种方式
1.(无名)管道
半双工,即不能同时在两个方向上传输数据。有的系统可能支持全双工。
只能在父子进程间。在经典的形式下,父进程创建管道,然后通过fork子进程,从而实现了父子进程之间的使用。
2.命名管道(FIFO)
不相关的进程也能够进行数据交换。
3.消息队列
一个消息队列是一组保存在内核中消息的列表,类似于一个消息的链表。用户进程可以向消息队列添加消息,也可以向消息队列读取消息。
消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。
可以把消息看做一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程可以从消息队列中读取消息。
4.信号量
当多个进程需要访问共享数据时,信号量是一个计数器,主要用于此目的。如果需要确保同一数据不会被两个进程同时访问,可以通过信号量来实现。
它的主要流程如下:
检查控制该资源的信号量
如果信号量值大于0,则资源可用,并且将其减1,表示当前已被使用
如果信号量值为0,则进程休眠直至信号量值大于0
也就是说,它实际上是提供了一个不同进程或者进程的不同线程之间访问同步的手段。
5.共享内存
共享内存允许两个或多个进程共享一个给定的存储区,这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中,一个进程写入共享内存的信息,可以被其他使用这个共享内存的进程,通过一个简单的内存读取错做读出,从而实现了进程间的通信。
采用共享内存进行通信的一个主要好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于像管道和消息队里等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。
一般而言,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时在重新建立共享内存区域;而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。由于共享内存中的内容通常在解除映射时才被写回文件,因此采用共享内存进行通信的方法具有极高的效率。
6.套接字Socket:
套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同计算机间的进程通信。
7.信号 ( sinal )
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生
以上是线程和进程有哪些关系的详细内容。更多信息请关注PHP中文网其他相关文章!