目录
练习:创建一个守护进程,循环间隔1s向文件中写入一串字符“hello”
进程
1》什么是进程
1> 概念
2> 特点
3> 进程段
4> 进程分类
5> 进程状态
6> 进程状态切换图
7> 进程相关命令
<补充>优先级调度
2》进程函数接口
1> 创建进程 fork()
特点:
2> 回收资源
wait 练习:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <wait.h>
int main(int argc, char const *argv[])
{
pid_t pid;
int a = 0;
pid = fork(); // 创建了一个子进程
if (pid < 0)
{
perror("fork err");
return -1;
}
else if (pid == 0)
{
printf("i am child process %d %d\n", getpid(), getppid());
sleep(3); // 让子进程睡眠 3 秒之后再结束
}
else
{
wait(NULL); // 给任意结束的子进程回收资源,如果没有子进程结束就会一直阻塞等待
// waitpid(-1,NULL,0); //代表阻塞,此时和wait(NULL)的效果一样
printf("i am parent process %d %d\n", pid, getpid());
while (1)
; // 为了让父进程不要结束
}
return 0;
}
waitpid 练习:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <wait.h>
int main(int argc, char const *argv[])
{
pid_t pid;
int a = 0;
pid = fork(); // 创建了一个子进程
if (pid < 0)
{
perror("fork err");
return -1;
}
else if (pid == 0)
{
printf("i am child process %d %d\n", getpid(), getppid());
sleep(3); // 让子进程睡眠 3 秒之后再结束
}
else
{
// wait(NULL); // 给任意结束的子进程回收资源,如果没有子进程结束就会一直阻塞等待
waitpid(-1, NULL, WNOHANG);//WNOHANG 代表不阻塞,此时当父进程执行到这句时,子进程可能处于睡眠状态,还未结束,这时就不会回收子进程资源,可能就会使子进程变成僵尸进程
//可以采用循环来解决这个问题,不停的检测是否有结束的子进程,直到回收了之后才结束
while (1)
{
if (waitpid(-1, NULL, WNOHANG) > 0)
break;
}
printf("i am parent process %d %d\n", pid, getpid());
while (1)
; // 为了让父进程不要结束
}
return 0;
}
3> 结束进程
exit 练习:
_exit 练习
4> 获取进程号
练习:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
pid_t pid;
pid = fork(); //创建了一个子进程
if (pid < 0)
{
perror("fork err");
return -1;
}
else if (pid == 0)
{
printf("i am child process:%d %d\n", getpid(), getppid());
}
else
{
printf("i am parent process: %d %d\n", pid, getpid());
}
while (1); //让父子进程都不要结束
return 0;
}
3》exec函数族
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
printf("hello\n");
//system("ls -l"); //原来进程不会被替换,执行完ls -l启动的进程之后继续执行原先进程
execl("/bin/ls","ls","-l",NULL); //原先进程被ls -l启动的进程替换了,所以后面打印语句不执行了
printf("world\n");
return 0;
}
4》守护进程
1> 守护进程的特点
2> 创建步骤
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <sys/stat.h>
int main(int argc, char const *argv[])
{
pid_t pid = fork();//创建子进程
if(pid<0)
{
perror("fork err");
return -1;
}
if(pid == 0)
{
setsid();//在子进程中创建新会话
chdir("/");//改变进程运行路径为根目录
umask(0);//重设文件权限掩码
for(int i=0;i<3;i++) //关闭默认打开的0 1 2
close(i);
while (1);
}
else
{
exit(0);
}
return 0;
}
练习:创建一个守护进程,循环间隔1s向文件中写入一串字符“hello”
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <wait.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
// FILE *fp;
// fp = fopen(argv[1], "a+");
// if (NULL == fp)
// {
// printf("open err\n");
// return -1;
// }
// printf("open success\n");
int fd;//定义一个变量接收文件描述符
fd = open(argv[1],O_RDWR);//打开命令行中文件
if(fd < 0)
{
printf("open err\n");
return -1;
}
printf("open success\n");
pid_t pid;//定义一个变量接收 fork()返回值
pid = fork();
if (pid < 0)//失败
{
perror("fork err\n");
return -1;
}
else if (pid == 0)//fork 返回值为 0 说明是子进程
{
printf("child\n");
setsid();//在子进程中创建新会话
chdir("/");//改变进程运行路径为根目录
umask(0);//重设文件权限掩码
for(int i=0;i<3;i++) //关闭默认打开的0 1 2
close(1);
while (1)
{
// fputs("hello", fp);
// fflush(NULL);
write(fd,"hello",5);//向文件中写入”hello“
sleep(1);//每隔 1 秒写入一次
}
//想要停止只能通过 kill -9 将守护进程杀死
while (1)
;
}
else
{
printf("parent\n");
// exit(0);
}
return 0;
}
3> 总结