Linux之多进程与多线程

        进程是UNIX系统中仅次于文件的基本抽象概念,当目标代码执行时,正在运行的进程不仅仅是汇编代码,而是由数据、资源、状态和虚拟的计算机组成。

1、程序、进程和线程区分

        程序(program)是指编译过的、可执行的二进制代码,保存在存储介质如磁盘上,不运行。规模很大的二进制程序集可以称为应用。

        进程(process)是指正在运行的程序。进程包括二进制镜像,加载到内存中,还涉及很多其他方面:虚拟内存示例、内核资源如打开的文件、安全上下文关联的用户,以及一个或多个线程。

        线程(thread)进程内的活动单元。每个线程包含自己的虚拟存储器,包括栈、进程状态如寄存器,以及指令指针。

        在单线程的进程中,进程即线程。一个进程只有一个虚拟内存实例,一个虚拟处理器。在多线程的进程中,一个进程有多个线程。由于虚拟内存是和进程关联的,所有线程会共享相同的内存地址空间。

2、进程ID

        每个进程都是由一个唯一的标识符表示的,即进程ID,简称pid。系统保证在任意时刻pid都是唯一的。

        空闲进程(idle process),即当没有其他程序在运行时,内核所运行的进程,其pid值为0。在启动后,内核运行的第一个进程称为init进程,其pid值为1。一般来说,Linux中init进程就是init程序。"init"这个术语不但表示内核运行的第一个进程,也表示完成该目的的程序名称。

        除非用户显示告诉内核要运行哪个程序(通过init内核命令行参数),否则内核就必须自己指定合适的init程序,这种情况很少见,是内核策略的一个特例。

Linux内核会尝试四个可执行文件,顺序如下:

(1)、/sbin/init:init最可能存在的地方,也是期望存在的地方。

(2)、/etc/init:Intit另一个可能存在的地方。

(3)、/bin/init:init可能存在的位置。

(4)、/bin/sh:Bourne Shell所在的位置,当内核没有找到init程序时,就会尝试运行它。

在以上四个可能位置中,最先被发现的就会当作init运行。如果四个运行都失败了,内核就会报警,系统挂起。内核交出控制后,init会接着完成后续的启动过程。一般而言,这个过程包括初始化系统、启动各种服务以及启动登录进程。

2.1 分配进程ID

        缺省情况下,内核将进程ID的最大值设置为32768,这是为了和老的UNIX系统兼容,因为这些系统使用了有符号16位数来表示进程ID,可以通过修改/proc/sys/kernel/pid_max把这个值设置成更大的值,但是会牺牲一些兼容性。

        内核分配进程ID是以严格的线性方式执行的。如果当前pid的最大值是17,那么分配给新进程的pid值就为18,即使当新进程开始运行时,pid为17的进程已经不再运行了。内核分配的pid值达到了/proc/sys/kernel/pid_max之后,才会重用以前已经分配过的pid值。因此,尽管内核不保证长时间的进程ID的唯一性,但这种分配方式至少可以保证pid在短时间内是稳定且唯一的。

2.2 进程体系

        创建新进程的那个进程称为父进程,而新进程被称为子进程。每个进程都是由其他进程创建的(除了init进程),因此每个子进程都有一个父进程。这种关系保存在每个进程的父进程ID号(ppid)中。

        每个进程都属于某个用户和某个组。这种从属关系可以用来实现访问控制。对于内核来说,用户和组都不过是些整数值。通过/etc/passwd和/etc/group这两个文件,这些整数被映射成人们易读的形式。每个子进程都继承了父进程的用户和组。

        每个进程都是某个进程组(process group)的一部分,进程组表示的是该进程和其他进程之间的关系,不应混淆。子进程通常属于其父进程所在的那个进程组。此外,当通过shell建立管道时(如用户输入了命令ls | less),所有和管道相关的命令都是同一个进程组。进程组这个概念使得在管道上的进程之间发送信号或者获取信息变得很容易,同样,也适用于管道中的子进程。从用户角度来看,进程组作业(iob)是紧密关联的。

2.3 pid_t

        进程ID是由数据类型pid_t来表示的,pid_t在头文件<sys/types.h>中定义,在Linux中,pid_t通常定义成C语言的int类型

2.4 获取进程ID和父进程ID

系统调用getpid()会返回调用进程的进程ID,用法如下:

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);

系统调用getppid()会返回调用进程的父进程ID,用法如下:

#include <sys/types.h>
#include <unistd.h>
pid_t getppid(void);

这两个系统调用都不会返回错误。

3、运行新进程

        在UNIX中,把程序载入内存并执行程序映像的操作与创建新进程的操作是分离的。一次系统调用会把二进制程序加载到内存中,替换地址空间原来的内容,并开始执行。这个过程称为“执行(executing)”一个新的程序,是通过一系列exec系统调用来完成的。

        同时,另一个不同的系统调用是用于创建一个新的进程,它基本上相当于复制其父进程。通常情况下,新的进程会立即执行新的程序。创建新进程的操作称为派生(fork),是系统调用fork()来完成这个功能。在新进程中执行一个新的程序需要两个步骤:首先,创建一个新的进程,然后,通过exec系统调用把新的二进制程序加载到改进程中。

3.1 exec系统调用

        不存在单一的exec函数,而是基于单个系统调用,由一系列的exec函数构成。我们先来看看其中最简单的调用execl():

#include <unistd.h>
int execl(const char *path,
          const char *arg,
          ...);

        

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux是一种支持多进程多线程的操作系统。多进程指一个程序可以被分成多个进程同时运行,每个进程拥有自己的内存空间和运行环境,它们之间通过进程间通信进行通信和数据共享;而多线程指一个进程中可以拥有多个线程并行执行,共享同一份内存空间和运行环境,具有更高的并发性和效率。Linux支持通过Thread模块、PThread库和POSIX等方式来实现多线程多进程多线程的应用广泛,可以使系统更加高效稳定和具有更好的用户体验。 ### 回答2: 首先,Linux多进程是指一个程序同时运行多个进程,每个进程有自己的空间和资源,互相独立。每个进程都可以独立执行,有自己的数据空间和代码空间,能够完成不同的任务。在Linux系统中,通过fork()系统调用可以创建新进程,通过exec()可以加载新程序到进程中。 相比之下,Linux多线程是在一个进程内部同时运行多个线程,每个线程共享同一个地址空间和资源。多线程可以提高程序的并发性,加快多个任务的执行速度。通过pthread_create()函数可以在程序中创建新线程。 在使用多进程时,每个进程独立运行,内存空间独立,因此进程之间的数据交换比较麻烦,需要通过网络、管道等手段进行通信。而多线程共享同一个地址空间,数据交换更加方便快捷,只需要在不同线程之间直接传递数据即可。 另外,多线程也可以避免上下文切换所带来的开销,因为线程切换比进程切换要快,所以多线程可以提高系统性能,但是多线程编程需要考虑线程之间的同步和互斥,以及死锁等问题,需要更加谨慎。 总的来说,Linux多进程多线程都有其适用的场景和优缺点,需要根据具体的需求来选择合适的编程方式。 ### 回答3: Linux是一种基于unix的操作系统,具有很强的稳定性和可靠性。Linux同时支持多进程多线程,这使得它在并发性方面具有优势。 多进程是指在同一时间内运行多个进程,每个进程之间相互独立,拥有自己的地址空间和资源。每个进程都有一个唯一的进程标识符pid,可以通过pid来查找和管理进程。多进程的好处是可以提高系统的并行效率,同时还能保证进程间数据的隔离性,但是进程间通信需要使用IPC(inter-process communication)机制,会导致一些额外的开销。 多线程是指在同一时间内运行多个线程,线程是轻量级的进程。同一个进程内的不同线程共享相同的地址空间和资源,更加高效。多线程的好处是可以提高系统的并发性,同时也可以共享进程内部的资源,减少进程间的通信开销。但是,多线程会涉及到线程同步和互斥问题,需要使用锁等机制来保证线程的安全性。 在应用程序的设计中,通常需要选择使用多进程还是多线程,这需要根据具体的应用场景来决定。如果应用程序需要执行不同的任务,或者每个任务需要使用不同的资源,则可以考虑使用多进程;如果需要执行相同的任务,但是需要对任务进行分割和分配,或者需要共享资源,则可以考虑使用多线程。 总之,Linux多进程多线程都可以提高系统的并发性和响应速度,但需要在具体场景下选择合适的方式来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值