1.怎么创建进程
创建mytest.c文件
输入下列代码
#include<stdio.h>
#include<unistd.h>
int main()
{
while(1)
{
printf("I am a process!\n");
sleep(1);
}
return 0;
}
创建makefile文件输入下列代码
mytest:mytest.c
gcc -o mytest mytest.c
.PHONY:clean
clean:
rm -f mytest
我们make一下,在把生成可执行程序mytest执行,那么mytest这个时候就是进程了
2.怎么查看进程
不过上面的那个grep是什么意思,那个其实是命令,我们使用过的命令,会自动变成一个个进程
不过要是不想显示grep也可以
grep -v grep的意思是匹配到grep就不显示,把没匹配到grep的给显示出来
而通过了解了linux的进程,windows的进程也了解,像打开游览器其实就是在打开一个进程
不过上面打印的那些东西看不懂,怎么办
打开下面命令
ps axj | head -1 && ps axj | grep mytest | grep -v grep
上面的pid其实就是进程id了,那么我们就去存在进程id的文件proc里面查找一下这个id
可以看到确实存在这个id
这个时候我们把可执行文件mytest暂停再执行,这个时候我们的进程id就变了,相当于创建了一个新的进程
我们输入ls /proc/进程号 -al
上面的exe代表着是进程对应的可执行程序的磁盘文件
上面的cwd代表着进程当前的工作路径
不过这样子查pid太浪费时间了
我们其实可以写代码来知道当前进程的进程id
改下之前写的mytest.c
可以看到pid一模一样
3.杀掉进程命令
输入kill -9 进程id,就可以向进程发出信号9的信号从而杀掉进程
4.进程的ppid
ppid其实就是父进程的id
获取ppid
代码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
while(1)
{
printf("I am a process! pid:%d ppid:%d\n",getpid(),getppid());
sleep(1);
}
return 0;
}
再看这里我期间把进程给暂停了,又重新打开,发现pid变了但是父进程id没变
我们查看一下父进程,从下面图片可以看到父进程是一个bash的东西
所以我们从这里看到几乎我们在命令行执行的所有命令,都是bash进程的子进程
5.fork函数
fork函数是用来创建子进程的,所以它会有二个返回值
如果成功了 父进程返回子进程的pid,给子进程返回0
我们来检验一下是不是真的,下面代码按我们上面讲的,他可能会打印二次
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
printf("hello fork\n");
return 0;
}
可以看到确实打印了二次
不过这个打印的太乱了,我们加个sleep(1);
除了这个还有一个奇怪的就是它们的pid
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
printf("hello fork id:%d\n", id);
sleep(1);
return 0;
}
打印结果,一个是2672一个是0
那么我们再来检验下面代码
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
//child
while(1)
{
printf("我是子进程,我的pid: %d,我的父进程是: %d\n", getpid(), getppid());
sleep(1);
}
}
else
{
//parent
while(1)
{
printf("我是父进程,我的pid: %d,我的父进程是: %d\n", getpid(), getppid());
sleep(1);
}
}
return 0;
}
按照C语言if和else是不会同时执行的,而且也不会出现二个死循环的
但是我们在linux执行上面代码来看看
上面的32716是base进程的id
可以看到出现了问题了子进程和父进程同时执行并死循环
因为fork以后,父进程和子进程会共享代码,一般都会执行之后的代码,所以才会打印二次的问题
fork以后,会有不同的返回值,可以通过不同的返回值,可以让父子进程执行不同的代码
1. fork()为什么给父进程返回子进程的pid,给子进程返回0
因为一个父亲可以有很多个儿子,但是儿子只有一个父亲,干爹除外,所以父进程必须要有标识子进程的方式,fork以后给父进程返回子进程的pid
子进程最重要的是知道自己被创建成功了,因为子进程找父进程的代价特别低,因为只有一个父进程,不像父进程找子进程
2.为什么fork会返回二次
fork是个函数,是由操作系统调用的 那么fork之后操作系统做了什么?
进程理论上是操作先描述再组织是父进程创建了,那么父进程是不是进程是的
那么怎么证明操作系统多了个进程,在操作系统里面等于 task_struct + 子进程和数据,子进程的task_struct是个对象,那么子进程里面的pid ppid它是怎么来的,基本上都是由父进程继承下来的,也可以说是拷贝下来的
那么这里又有一个问题,子进程的代码从哪里来,他没有从哪里来只是和父进程共用一份,这就是fork之后,父子进程代码共享,但是数据是各自独立的,所以可以通过不同的返回值来,让父子进程分别实现不同的代码