进程的相关概念

      多进程
             进程相关的概念
             linux提供的进程有关的接口函数
             进程间的通信
       多线程
             线程相关的概念
             linux提供的线程有关的接口函数 
             线程的同步与互斥
       线程池(难)
             综合运用了结构体,单链表,函数指针,多线程有关的知识点
       多进程多线程:都是为了解决多任务的并发(同时)执行,能够实现同时做多件事情
                     孙悟空--》一个人打不过10万天兵天将
                           --》解决方法--》拔毛--》变小猴子出来
                     360安全卫士--》并发执行多个任务
                     windows系统--》并发执行多个任务
                     linux系统--》并发执行很多任务

多进程
==============================
   1.进程相关的理论概念
            什么是进程:动态的,一个正在运行的程序就是一个进程,一旦程序运行起来,操作系统会自动创建一个进程来代表你运行的这个程序  
            程序:用编译器编译得到的二进制文件,是静态的
            linux提供的跟进程有关的shell命令
                     ps  -elf   (p --》process进程   s --》state状态)
            进程的组成:代码段+数据段+进程控制块(PCB)三部分组成
                代码段:用来存放你的程序代码
                数据段:用来存放你运行的程序中用到的各种数据
            进程控制块(process contrl block):指的是系统中提供的一个结构体,该结构体用来存放跟进程有关的状态信息
                      切换成超级用户,然后在根目录下查找
                          find  /  -name  sched.h
                      /usr/src/linux-headers-4.15.0-142/include/linux/sched.h头文件的第560行定义了如下结构体
                      struct  task_struct  //把这个结构体叫做进程控制块
                      {
                            
                              pid;  //进程的id号,无符号的整数

                      }
            父进程:调用fork的那个进程就是父进程
            子进程:fork调用成功,产生的就是子进程
                       int  main()
                       {
                            fork();  //产生子进程
                       }
            孤儿进程(爸爸去哪了):父进程优先于子进程退出,导致子进程没有人回收它的资源,此时子进程就变成了孤儿进程
            不同版本的Ubuntu针对孤儿进程采取的措施是不同:
                     有些ubuntu针对孤儿进程,采用阻塞的方式(孤儿进程卡住了)
                     有些ubuntu针对孤儿进程,让操作系统自己去回收孤儿进程
            进程组:多个进程组成的一个集合
   
   2.linux进程有关的接口函数
         (1)创建子进程
                 pid_t fork(void);
                    返回值(重点):无符号的整数,该函数并不复杂,复杂的是如何理解返回值
                              > 0   表示父进程,此时返回值表示的是子进程的ID号
                              ==0   表示子进程
                              < 0   表示fork调用失败
             疑问一:两个死循环都没有退出条件,为什么可以同时执行(并发执行)??
                     fork调用成功,会给子进程分配独立的内存空间(子进程不依赖父进程的地址空间)
                     父子进程相互独立运行
             疑问二:id>0和id==0两个矛盾的条件,竟然都成立--》见到鬼了
                     fork这个函数很特殊,一次调用,返回两次
                       id=fork();
                       子进程的代码如何区分表示呢??
                       父进程的代码如何区分表示呢??
                       if(id>0)
                       {
                          父进程的代码
                       }
                       else if(id==0)
                       {
                          子进程的代码
                       }
           (2)进程的退出与回收
                  进程的退出:就是结束进程
                        void exit(int status);
                              参数:status --》进程的退出值
                        void _exit(int status);            
                              参数:status --》进程的退出值
                  进程的回收:父进程在退出之前,主动调用函数去回收子进程的资源
                  为什么要回收子进程:如果你不回收,子进程很有可以变成孤儿进程
                        #include <sys/wait.h>
                        pid_t wait(int *stat_loc);
                              返回值:你回收到的那个子进程的ID号
                                参数:(重点)stat_loc --》存放进程退出时候的状态信息
                                      状态信息:包含了退出值,还包含了其它信息(子进程是否正常退出,异常退出,是哪个信号搞死它的)

                        pid_t waitpid(pid_t pid, int *stat_loc, int options);
                              返回值:你回收到的那个子进程的ID号
                                参数:pid --》 <0   表示回收进程组ID号是pid绝对值的其中一个进程
                                                    比如:waitpid(-2000,) //我要回收进程组ID号是2000的这个组里面其中一个进程
                                               -1   表示回收任意一个进程
                                                    比如:waitpid(-1,)  //我要回收任意一个进程
                                               0    表示回收本进程组内的任意一个进程
                                              >0    表示我想回收id号是pid的这个进程
                                                    比如:waitpid(2000,)  //我要回收ID是2000这个进程
 
                                      stat_loc --》存放进程退出时候的状态信息
                                      options --》WNOHANG   父进程回收子进程的时候,如果子进程还没有来得及退出,那么waitpid不会阻塞,会直接结束
                                                  0         阻塞等待,跟wait作用一样
                        特点:wait/waitpid会阻塞父进程,等待子进程退出,如果子进程一直不退出,wait/waitpid会让你的父进程一直阻塞
             (3)获取当前进程的ID号/父进程的ID号
                      pid_t getpid(void);
                            返回值: 返回当前进程的ID号   %hu
                      pid_t getppid(void);
                            返回值: 返回父进程的ID号     %hu 

#include "myhead.h"
//用多进程来模拟360安全卫士
//父进程死循环打印我正在杀毒
//子进程死循环打印我正在清除垃圾
int main() //主函数本身就代表一个进程
{
	printf("主函数(父进程运行起来了)!\n");
	
	//创建一个子进程出来--》生个仔
	pid_t id=fork();
	if(id>0)  //父进程
	{
		while(1)
		{
			printf("我是父进程,我在杀毒!\n");
			sleep(1);
		}
	}
	else if(id==0)  //子进程
	{
		while(1)
		{
			printf("我是子进程,我在清除垃圾!\n");
			sleep(1);
		}
	}
	else 
	{
		printf("fork调用失败!\n");
		return -1;
	}
}

 

#include "myhead.h"

//定义全局变量
int globala=666;

int main() //主函数本身就代表一个进程
{
	printf("主函数(父进程运行起来了)!\n");
	
	//定义局部变量
	int n=123;
	
	//创建一个子进程出来--》生个仔
	pid_t id=fork();
	if(id>0)  //父进程
	{
		while(1)
		{
			printf("我是父进程,全局变量的值是:%d\n",globala);
			printf("我是父进程,局部变量的值是n:%d   id:%lu\n",n++,id);
			sleep(1);
		}
	}
	else if(id==0)  //子进程
	{
		//子进程偷偷摸摸修改全局变量的值
		globala=888;
		while(1)
		{
			printf("我是子进程,全局变量的值是:%d!\n",globala);
			printf("我是子进程,局部变量的值是n:%d   id:%lu\n",n,id);
			sleep(1);
		}
	}
	else 
	{
		printf("fork调用失败!\n");
		return -1;
	}
}
#include "myhead.h"

int main()
{
	int status;
	printf("fork调用之前的代码!\n");
	//创建一个子进程
	pid_t id=fork();
	if(id==0)  //子进程
	{
		printf("子进程运行了!\n");
		//while(1)
		//{
			
		//}
		//结束/退出子进程
		exit(3); 
	}
	else if(id>0) //父进程
	{
		printf("父进程运行了,子进程的ID号是:%hu!\n",id);
	}
	
	printf("主函数(父进程)准备退出了.......!\n");
	//回收子进程 --》防止子进程变成孤儿(僵尸进程/僵死进程)进程
	//pid_t ret=waitpid(id,&status,WNOHANG);  //WNOHANG非阻塞等待(等得了就等,等不了就退出)
	//pid_t ret=waitpid(id,&status,0);  //0表示阻塞等待
	//pid_t ret=waitpid(-1,&status,0);
	pid_t ret=waitpid(0,&status,0);
	printf("我回收的那个子进程ID是:%hu\n",ret);
	//判断子进程是不是正常退出的
	if(WIFEXITED(status))
		printf("你的仔是正常退出的!\n");
	else
		printf("你的仔是异常退出的!\n");
	printf("子进程的退出值:%d\n",WEXITSTATUS(status));
	return 0;
}
#include "myhead.h"

int main()
{
	int status;
	printf("fork调用之前的代码!\n");
	//创建一个子进程
	pid_t id=fork();
	if(id==0)  //子进程
	{
		printf("子进程运行了!\n");
		while(1)
		{
			
		}
		//结束/退出子进程
		exit(3); 
	}
	else if(id>0) //父进程
	{
		printf("父进程运行了,子进程的ID号是:%hu!\n",id);
	}
	
	printf("主函数(父进程)准备退出了.......!\n");
	//回收子进程 --》防止子进程变成孤儿(僵尸进程/僵死进程)进程
	//pid_t ret=wait(NULL);
	pid_t ret=wait(&status);
	printf("我回收的那个子进程ID是:%hu\n",ret);
	//判断子进程是不是正常退出的
	if(WIFEXITED(status))
		printf("你的仔是正常退出的!\n");
	else
		printf("你的仔是异常退出的!\n");
	printf("子进程的退出值:%d\n",WEXITSTATUS(status));
	return 0;
}
#include "myhead.h"

int main()
{
	printf("fork调用之前的代码!\n");
	//创建一个子进程
	pid_t id=fork();
	if(id==0)  //子进程
	{
		printf("子进程运行了!\n");
		while(1) //目的让子进程不要结束
		{
			
		}
		//结束/退出子进程
		exit(1); 
	}
	else if(id>0) //父进程
	{
		printf("父进程运行了,子进程的ID号是:%hu!\n",id);
	}
	
	printf("主函数(父进程)准备退出了.......!\n");
	//回收子进程 --》防止子进程变成孤儿(僵尸进程/僵死进程)进程
	pid_t ret=wait(NULL);
	printf("我回收的那个子进程ID是:%hu\n",ret);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hqb_newfarmer

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

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

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

打赏作者

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

抵扣说明:

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

余额充值