线程与进程

总结:线程是进程中的实体,是系统分派和调度的基本单元,进程是系统分配资源的基本单单元,多线程本身不占用系统资源,只是共享和使用同一进程的地址空间和资源,所以开辟多线程的时候的开销要比多进程要小,它只需要建立线程的相关控制表和有关队列,无需开辟地址空间和所需资源,由于多线程工作在同一进程的地址空间,共享内存和数据资源,无需内核参与通讯,而多进程之间往往需要内核的参与,提供通讯机制和保护机制,cpu在多线程之间的开销也要比多进程中要小。

线程:

线程是进程中的一个实体,作为系统调度和分派的基本单位。Linux下的线程看作轻量级进程。

线程的性质:

1.线程是进程内的一个相对独立的可执行的单元。若把进程称为任务的话,那么线程则是应用中的一个子任务的执行。

2.由于线程是被调度的基本单元,而进程不是调度单元。所以,每个进程在创建时,至少需要同时为该进程创建一个线程。即进程中至少要有一个或一个以上的线程,否则该进程无法被调度执行。

3.进程是被分给并拥有资源的基本单元。同一进程内的多个线程共享该进程的资源,但线程并不拥有资源,只是使用他们。

4.线程是操作系统中基本调度单元,因此线程中应包含有调度所需要的必要信息,且在生命周期中有状态的变化。

5.由于共享资源【包括数据和文件】,所以线程间需要通信和同步机制,且需要时线程可以创建其他线程,但线程间不存在父子关系。

多线程使用的情形:前台和后台工作情况;异步处理工作情况;需要加快执行速度情况;组织复杂工作的情况;同时有多个用户服务请求的情况等。

 线程机制的优点:

多线程运行在同一个进程的相同的地址空间内,和采用多进程相比有以下优点:

1.创建和撤销线程的开销较之进程要少。创建线程时只需要建立线程控制表相应的表目,或有关队列,而创建进程时,要创建PCB表和初始化,进入有关进程队列,建立它的地址空间和所需资源等。

2.CPU在线程之间开关时的开销远比进程要少得多。因开关线程都在同一地址空间内,只需修改线程控制表或队列,不涉及地址空间和其他工作。

3.线程机制也增加了通讯的有效性。进程间的通讯往往要求内核的参与,以提供通讯机制和保护机制,而线程间的通讯是在同一进程的地址空间内,共享内存和文件,无需内核参与。

多线程之间的通信方式:

1.全局变量 2.消息队列 3.事件

同步方式:

1.互斥锁 2.信号灯 3.条件变量

进程间通信方式:

管道,有名管道,消息队列,共享内存,套接字,信号量,信号

cpu:中央处理器,用来处理指令 执行操作 控制时间 处理数据

内存:是与CPU进行沟通的桥梁,作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据

主频:表示在cpu内数字脉冲中信号震荡的速度

进程间的通信的方式有6种:管道通信,信号通信,共享内存,消息队列,信号量,套接字。

管道 又分为无名管道与有名管道。无名管道用于子进程与父进程之间通信,有名管道用于任一两个进程之间的通信。数据只能单向流动并且容易出现进程阻塞。

消息队列 传递信息量多,不受缓冲器大小的限制

共享内存 通信速度最快

套接字   可用于不同及其间的进程通信

信号量   可以控制多个进程对共享资源的访问。主要作为进程间以及同一进程内不同线程之间的同步手段

信号通信 比较负责,用于通知接受进程某个事件已经发生

进程:是计算机中已运行程序的实体。进程本身不会运行,是线程的容器。程序本身只是指令的集合,进程才是程序(那些指令)的真正运行。若干进程有可能与同一个程序相关系,且每个进程皆可以同步(循序)或不同步(平行)的方式独立运行。进程为现今分时系统的基本运作单位

一个进程可以有很多线程,每条线程并行执行不同的任务。

进程是资源分配的最小单位,线程是CPU调度的最小单位。

线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体 线程的运行中需要使用计算机的内存资源和CPU。

线程和进程的区别(一定要背下来,并且能够结合自己的项目行进阐述)

线程是指进程内的一个执行单元,也是进程内的可调用实体,与进程的区别:

(1)调度:线程作为调度和分配的基本单元,进程作为拥有资源的基本单位;

(2)并发性:不仅进程之间可以并发执行,同一个进程之间的多个线程也可以并发执行;

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源但可以访问隶属于进程的资源;

(4)系统开销:在创建或撤销进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤销线程时的开销

1.什么时候选择多线程,什么时候采用多进程?

    强相关的时候使用多线程,弱相关的时候使用多进程,但是对其没有明确的规定。一般情况是进程与线程结合使用。

2.谈谈你对进程的理解?内核是如何管理进程的?

首先,进程是资源分配的基本单位,一个程序就是一个进程。进程有三个状态。执行状态,阻塞状态,就绪状态。内核调度器通过不同的调度方法选择最值得运行的进程。

执行状态:进程正在占用CPU    阻塞状态:正在执行的进程,由于等待某个事件的发生而无法执行   就绪状态:进程已经具备执行一切的条件,等待分配CPU的处理时间片

3.多进程编程的优缺点?

优点:当多进程中的一个进程出现异常,其他进程不受任何影响。可靠性高。

缺点:存在进程互斥情况。当多个进程需要某一共享资源的时候,任何时候只允许一个进程使用。其他进程要使用的时候只能进行等待,等到资源被释放后才可以使用。占用内存多。

孤儿进程的存在 是因为 父进程先于子进程退出,那么子进程会变成孤儿进程

僵尸进程的存在 是因为 子进程退出后,父进程并没有调用wait()或者 waitpid(),子进程的描述符还保留在系统中

它需要它的父进程来为它收尸,如果他的父进程没调用wait或waitpid()等待子进程结束,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动 会接手这个子进程,为它收尸,它还是能被清除的

孤儿进程最后会被init接管,而僵尸进程会继续占用资源

PCB是系统对进程的唯一标识,进程标识符PID,父进程标识符PPID,

获取本进程ID

pid_t getpid(void)

获取父进程ID

pid_t getppid(void)

创建多线程

pthread_create

线程分离

pthread_detach(pthread_self());

1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放??

2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.

3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦

创建子进程

pid_t fork(void)   

fork被调用一次,返回两次

1、在父进程中,fork返回新创建的子进程的PID;

2、在子进程中,fork返回0;

3、如果出现错误,fork返回一个负值

注意:

1. fork完后创建两个进程,每个进程从fork()返回继续执行

2. 两个进程执行相同的代码段,但都有各自的栈区,堆区,数据段

3. fork完后两个进程哪个先执行不确定

 pid_t vfork(void);

 

区别:1.   fork:子进程拷贝父进程的数据段     

            vfork:子进程与父进程共享数据段

           2. fork:父、子进程的执行次序不确定

             vfork:子进程先运行,父进程后运行

进程等待

pid_t wait(int *status);

pid = wait(NULL);

如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD

进程退出

_exit立即进入内核

exit先执行一些清理处理(调用各终止处理程序、关闭所有标准I/O流等),然后进入内核。

#include <stdlib.h>

void exit(int status);

#include <unistd.h>

void _exit(int status);

(echo $?正常退出为0,非正常退出打印退出码)

1. 死锁:

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去如果一组进程中的每一个进程都在等待仅由该组进程中的其它进程才能引发的事件,那么该组进程是死锁的。

2.可剥夺资源和不可剥夺资源:

可剥夺资源是指某进程在获得该类资源时,该资源同样可以被其他进程或系统剥夺,不可剥夺资源是指当系统把该类资源分配给某个进程时,不能强制收回,只能在该进程使用完成后自动释放 

3.产生死锁的原因:

1.竞争不可剥夺资源:系统中不可剥夺资源的数目不足以满足诸进程运行的要求,则发生在运行进程中,不同的进程因争夺这些资源陷入僵局。

举例说明:  资源A,B; 进程C,D

资源A,B都是不可剥夺资源:一个进程申请了之后,不能强制收回,只能进程结束之后自动释放。内存就是可剥夺资源

进程C申请了资源A,进程D申请了资源B。

接下来C的操作用到资源B,D的资源用到资源A。但是C,D都得不到接下来的资源,那么就引发了死锁

2.竞争临时资源

3.进程推进顺序不当发生死锁

4.产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不可抢占条件:进程已获得的资源,在末使用完之前,不能强行剥夺,只能在进程使用完时由自己释放。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。因此可以写下如下的预防死锁的方法。

5.避免死锁的方法:

(1)破坏“互斥”条件:就是在系统里取消互斥。若资源不被一个进程独占使用,那么死锁是肯定不会发生的。但一般“互斥”条件是无法破坏的。因此,在死锁预防里主要是破坏其他三个必要条件,而不去涉及破坏“互斥”条件。

(2)破坏“请求和保持”条件:在系统中不允许进程在已获得某种资源的情况下,申请其他资源。即要想出一个办法阻止在持有资源的同时申请其他资源。

方法一:所有进程在运行之前,必须一次性地申请在整个运行过程中所需的全部资源。这样,该进程在整个运行期间,便不会再提出资源请求,从而破坏了“请求”条件。系统在分配资源时,只要有一种资源不能满足进程的要求,即使其它所需的各资源都空闲也不分配给该进程,而让该进程等待。由于该进程在等待期间未占有任何资源,于是破坏了“保持”条件。

该方法优点:简单、易行且安全。

缺点:a.资源被严重浪费,严重恶化了资源的利用率。

      b.使进程经常会发生饥饿现象。

方法二:要求每个进程提出新的资源申请前,释放它所占有的资源。这样,一个进程在需要资源S时,须先把它先前占有的资源R释放掉,然后才能提出对S的申请,即使它可能很快又

(3)破坏“不可抢占”条件:允许对资源实行抢夺。

方法一:如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源。

方法二:如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。只有在任意两个进程的优先级都不相同的条件下,该方法才能预防死锁。

(4)破坏“循环等待”条件:将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出。这样做就能保证系统不出现死锁。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半岛铁盒.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值