进程和线程
进程和线程的区别
进程是操作系统进行资源分配的基本单位。进程控制块 (Process Control Block, PCB) 描述进程的基本信息和运行状态,所谓的创建进程和撤销进程,都是指对 PCB 的操作。一个进程中可以有多个线程,线程是独立调度的基本单位。同一个进程中的多个线程之间可以并发执行,它们共享进程资源。
进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间。线程属于进程,多线程共享同一进程的资源。
- 地址空间与其他资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其他进程不可见。
- 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要线程同步和互斥手段的辅助,以保证数据的一致性。
- 调度和切换:线程上下文切换比进程上下文切换要快得多。并且线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。
- 系统开销:由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,因此操作系统所付出的开销远大于创建或撤销线程时的开销。类似地,在进行进程切换时,涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置。而线程切换时只需保存和设置少量寄存器内容,开销很小。
进程间通信的方式。
进程间通信基本上有5种通讯方式。
-
无名管道通信:效率低,只有父子进程能通信,但简单。
进程中用pipe(int fd[2])创建一个匿名管道,管道也是文件,返回2个文件描述符,fd[0]是读入端,fd[1]是写入端。
若以文件的形式存储,ls的时候可以看到
prw-r--r--
,p就是pipe管道。$ echo "hello" > myPipe # 将数据写进管道 这里会阻塞,只有当管道里的数据被读完后,命令才可以正常退出。 $ cat < myPipe # 读取管道里的数据,此时myPipe就可以退出了
-
有名管道:即FIFO队列,任何进程间都能通信,效率低。
-
消息队列:管道不适合进程间频繁地交换数据,而消息队列可以。消息队列生命周期随内核。底层是保存在内核中的消息链表,存储的是用户自定义的消息体。但消息队列不适合较大数据的传输。
-
共享内存区:分配一个每个进程都可以直接访问的共享空间,因此通信效率大大提升,但多进程竞争资源会有同步问题,相当于线程中的线程安全。
-
信号量:不能传递复杂消息,只能用来同步,保护资源,底层是一个计数器。
-
信号:基于事件监听和回调机制完成通信,是唯一的异步通信机制。
-
Socket:要与不同主机的进程间通信,那么就需要 Socket 通信了