前言
1、进程:指一个具有独立功能的程序在某个数据集合上的一次动态执行过程,它是操作系统进行资源分配和调度的基本单元。
2、你说上面的没看懂,那继续解释:
(1)任务:指由一个软件完成的活动,或者是为实现某个目的的一系列操作
(2)一个任务就是软件的一次运行,一个任务包含一个或多个子任务,这个子任务就是进程
3、使用fork函数新建子进程,它会完全复制父进程,子进程独有的只有它的进程号、资源使用和计时器
4、父子进程一个很重要的区别就是使用fork函数时,父进程返回的是子进程的进程号,而子进程返回0
一、进程的相关函数
1、fork函数
功能:从以存在的进程中创建一个新进程
新进程称为子进程,原进程称为父进程
头文件:
#include<sys/types.h>
#include<unistd.h>
函数原型:
pid_t fork(void);
例子:
pid_t pid;
pid=fork();
函数返回值:
0 子进程
大于0 父进程
2、exit函数
功能:直接使进程停止运行,如果缓冲区里存在数据,将数据写入文件中
头文件:
#include<stdlib.h>
函数原型:
void exit(int status);
例子:
exit(0);
3、wait函数
功能:父进程会阻塞等待子进程结束,并回收子进程资源
头文件:
#include<sys/types.h>
#include<sys/wait.h>
函数原型:
pid_t wait(int *status);
例子:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid = fork();
if(pid == 0) //fork返回值为0 说明子进程在执行
{
sleep(10);
printf("child is running, my id is %d\n", getpid());
}
else if(pid > 0) //返回值 > 0 说明父进程在执行
{
wait(NULL);
printf("parent is running, my id is %d\n", getpid());
}
}
4、exec函数族
功能:在进程中执行另一个程序的方法,执行完后,当前进程除了进程号外其他内容都被替换了
头文件:
#include<unistd.h>
函数原型:
int execl(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execle(const char *path,const char *arg,...,char *const envp[]);
int execve(const char *path,char *const argv[],char *const envp[]);
int execlp(const char *file,const char *arg,...);
int execvp(const char *file,char *const argv[]);
例子(只举了execlp函数的例子):
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid = fork();
if(pid == 0)
{
execlp("ls", "ls", "-l", NULL);
}
else if(pid > 0)
{
wait(NULL);
printf("pid is %d\n", pid);
}
}
二、创建守护进程
流程:
1、fork()创建子进程,exit()使父进程退出
2、setsid()创建新会话
3、chdir(“/”)设置工作目录
4、umask(0)重设文件权限掩码
5、close()关闭文件描述符
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t pid; //进程号变量
int i, fd;
char *buf = "This is a Daemon\n";
pid = fork(); //创建一个新进程
if(pid < 0) //pid小于0,创建新进程失败
{
printf("Error fork\n");
exit(1); //退出父进程
}
else if(pid > 0) //子进程创建成功
{
exit(0); //退出父进程
}
setsid(); //创建新会话
chdir("/tmp"); //设置工作目录
umask(0); //更改文件权限
for(i = 0; i < getdtablesize(); i++)
{
close(i); //关闭文件描述符
}
while(1)
{
if((fd = open("daemon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0) //打开文件daemon.log
{
printf("Open file error\n");
exit(1);
}
write(fd, buf, strlen(buf));//将buf的内容写进文件中
sleep(2);//阻塞2秒
close(fd);//关闭文件描述符
}
exit(0); //关闭子进程,但是while死循环,根本关闭不了
}