漫谈进程与线程

1. 进程

在此之前先理解一个概念:
在Unix/Linux系统中,正常情况下,子进程是由父进程创建的,但是子进程的结束与父进程的运行是一个异步过程,也就是说,父进程无法预测子进程的结束时间。当一个进程完成它的工作终止之后,父进程需要调用wait和waitpid获得子进程的最终状态,调用后才会释放子进程的剩余信息。

1.1 进程的含义

进程是并发执行的程序在执行过程中分配和管理资源的基本单位。

1.2 进程的三种状态
  • 就绪态:具备了一切运行需要的条件,由于其他进程占用CPU而暂时无法运行
  • 运行态:获得CPU的进程处于此状态,对应的程序在CPU上运行着
  • 阻塞态:为了等待某个外部事件的发送,暂时无法运行
状态之间的转化
1.3 进程控制块(PCB)

PCB是进程的唯一标识。进程创建时,为该进程生成一个PCB,进程终止时,回收PCB。

PID
每个进程都有唯一的PID,但是PID是可以重用的。当进程终止时,其他创建的新进程可能会使用该PID。
PID=0:该进程属于系统进程。
PID=1:该进程为普通用户进程,以超级用户特权运行。
PID=2:守护进程,负责支持虚拟存储系统的分页操作

1.4 进程的创建

先新建一个PCB,然后将父进程的PCB复制到新建的PCB中,再修改部分数据,分配新的内核堆栈,新的PID等,最后将PCB添加到node节点下,也就是链表中。(PCB是由链表实现的)

1.5 与进程有关的几个函数 fork,vfork
1.5.1 fork

fork函数时调用一次,返回两次。在父进程和子进程中各调用一次。子进程中返回值为0,父进程中返回值为子进程的PID。程序员可以根据返回值的不同让父进程和子进程执行不同的代码。

int main()
{
 pid_t pid;
 char *message;
 int n = 0;
 pid = fork();
 while(1){
 if(pid < 0){
 perror("fork failed\n");
 exit(1);
 }
 else if(pid == 0){
 n--;
 printf("child's n is:%d\n",n);
 }
 else{
 n++;
 printf("parent's n is:%d\n",n);
 }
 sleep(1);
 }
 exit(0);
}

上面程序执行的结果如下

执行结构

可以发现最后child比parent先调用了,且父进程和子进程各自的变量不相互影响
一般来说,fork之后父、子进程执行顺序是不确定的,这取决于内核调度算法。进程之间实现同步需要进行进程通信。

什么时候使用fork
一个父进程希望子进程同时执行不同的代码段,这在网络服务器中常见——父进程等待客户端的服务请求,当请求到达时,父进程调用fork,使子进程处理此请求。

1.5.1 vfork

它与fork相同的地方就是它们的返回值相同。但是fork创建子进程的时候会将父进程的数据空间、堆栈复制一份。而vfork创建子进程,与父进程内存数据共享。并且vfork保证子进程先执行,只有在子进程调用exit()或者exec后,父进程才往下执行

int main()
{
 pid_t pid;
 char *message;
 int n = 0;
 int i;
 pid = vfork();
 for(i = 0; i < 10; i++){
 if(pid < 0){
 perror("fork failed\n");
 exit(1);
 }
 else if(pid == 0){
 n--;
 printf("child's n is:%d\n",n);
 if(i == 1)
 _exit(0);
 //return 0;
 //exit(0);
 }
 else{
 n++;
 printf("parent's n is:%d\n",n);
 }
 sleep(1);
 }
 exit(0);
}

上面程序的运行结果如下:

运行结果

可以发现子进程先被执行,exit后,父进程才被执行,同时子进程改变了父进程中的数据
如果上面程序的子进程return 0会发生什么

子进程return0的结果

如果你在子进程中return,那么基本是下面的过程: 1)子进程的main() 函数 return了,于是程序的函数栈发生了变化。 2)而main()函数return后,通常会调用 exit()或相似的函数(如:_exit(),exitgroup()) 3)这时,父进程收到子进程exit(),开始从vfork返回,但是此时栈已经发生变化(其实就是刚才存在的栈被弹出了)

1.6 僵尸进程

当父进程用fork创建子进程的时候,如果子进程退出,父进程没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符会依旧保存在系统中,那么这种进程就叫做僵尸进程。

僵尸进程的危害
如果进程不调用wait和waitpid的话,子进程剩余的信息就不会释放,它的进程号会一直被占用。但是操作系统分配的进程号又是有限的,如果有大量的僵尸进程,那么就有大量的进程号无法使用,这样可能会导致无法新建进程。

1.7 孤儿进程

如果父进程先退出,它的子进程还在运行,那么这些子进程就会变为孤儿进程,会被init进程收养,后面它们的父进程就是init进程。

1.8 守护进程

守护进程其实也是一个孤儿进程,它的父进程就是init进程。

守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些待发生的事件。它不需要用户输入就能运行并且提供服务。

守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都在运行,守护进程经常以超级用户(root)权限运行。

常见的守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器mysqld等。

2. 线程

在网络或多用户的环境下,一个服务器往往要接收大量且不确定数量的用户的并发请求,如果给每一个用户都开一个进程,显然是不可能的,所以就引入了线程的概念。

2.1 线程的含义

单个线程的进程是单线程。
线程共享进程的地址空间,线程是处理器调度的基本单位。

线程私有和共享哪些资源

  • 线程私有:线程栈,寄存器,程序计数器
  • 线程共享:堆,地址空间,全局变量,静态变量
2.2 线程的同步与互斥

同步:多个线程为了合作完成某任务,按照先来后到的顺序执行
互斥:线程中的某些资源,一次只能允许一个线程进行访问,在这个线程进行访问的期间,其他线程不能访问该资源。

多线程同步和互斥的实现方法
互斥量 :只有01两个值
读写锁
临界区
信号量:信号量在计数大于0时表示触发状态,等于0表示资源已经耗尽,故信号量处于末触发。在对信号量调用等待函数时,等待函数会检查信号量的当前资源计数,如果大于0(即信号量处于触发状态),减1后返回让调用线程继续执行。一个线程可以多次调用等待函数来减小信号量。
条件变量
事件:用来通知线程有一些事件已发生,从而启动后继任务的开始

多线程的同步机制

  • 临界区:不可以跨进程,忘记解锁会无限等待,要么存在要么没有,多线程访问独占性共享资源

  • 互斥量:可以跨进程,忘记解锁会自动释放,要么存在要么没有

  • 事件:又叫线程触发器,不可以跨进程,要么存在要么没有,一个线程来唤醒另一个线程(包括自动和人工两种方式)

  • 信号量:可以跨进程,始终代表可用资源数量,当资源数为0时,线程阻塞,允许多个线程同时访问一个共享资源

引用:
进程详解(1)——可能是最深入浅出的进程学习笔记

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容