1.getpid和getppid函数
在C语言中,getpid()
函数用于获取当前进程的进程ID(Process ID),返回一个整数值。该函数不接受任何参数。
示例代码如下:
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid = getpid();
printf("当前进程的进程ID:%d\n", pid);
return 0;
}
getppid()
函数用于获取当前进程的父进程的进程ID(Parent Process ID),返回一个整数值。同样,该函数不接受任何参数。
示例代码如下:
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t ppid = getppid();
printf("父进程的进程ID:%d\n", ppid);
return 0;
}
需要注意的是,这两个函数需要在unistd.h
头文件中进行声明。
2.exit和_exit函数
在C语言中,exit和_exit函数都用于终止程序的执行,但是有一些区别。
-
exit函数:
- 声明:
void exit(int status);
- 参数类型:int
- 功能:调用exit函数会立即终止程序的执行,并返回一个整数值作为程序的退出状态。退出状态可以表示程序的执行结果或出错情况等信息。
- 运行时行为:调用exit函数时,程序会依次执行注册的终止处理函数(通过atexit函数注册的),关闭所有的打开文件,并清空缓冲区,最后通过_exit系统调用退出程序。
- 声明:
-
_exit函数:
- 声明:
void _exit(int status);
- 参数类型:int
- 功能:调用_exit函数会立即终止程序的执行,不会进行任何清理工作。不会调用终止处理函数,不会关闭文件或清空缓冲区。
- 运行时行为:调用_exit函数时,程序会直接通过_exit系统调用退出程序,不进行任何处理。
- 声明:
需要注意的是,exit函数会在正常终止程序或者异常终止程序时被调用。而_exit函数主要用于在异常情况下终止程序的执行,比如出现严重错误或者进程被强制终止。
3.wait和waitpid函数
在C语言中,wait和waitpid函数用于等待子进程的结束。
wait函数的原型如下:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
waitpid函数的原型如下:
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
这两个函数的参数意义如下:
pid
:需要等待的子进程的进程ID。若指定为-1,则表示等待任意子进程结束。status
:存储子进程终止状态的变量的地址。options
:额外的选项。详细说明如下:WNOHANG
:如果没有终止的子进程可用,则立即返回0,而不是阻塞等待。WUNTRACED
:如果子进程进入暂停状态,则也立即返回。这对于跟踪子进程的状态非常有用。
这两个函数的返回值为子进程的进程ID,或者-1表示出错。
使用这两个函数的一般步骤如下:
- 父进程使用fork函数创建子进程。
- 子进程执行相应的任务。
- 父进程调用wait或waitpid函数等待子进程的结束,获取子进程的终止状态。
- 父进程根据子进程的终止状态进行相应的处理。
作业:创建3个进程,子进1程拷贝文件的前一半,子进程2拷贝后一半文件,父进程回收两个子进程资源。
#include <myhead.h>
int up_text()
{
int fd1,fd2;
char buff[1024];
int len;
fd1=open("./1.txt",O_RDONLY);
if(fd1==-1)
{
perror("open");
return -1;
}
len=lseek(fd1,0,SEEK_END);
if(len==-1)
{
printf("拷贝失败\n");
close(fd1);
}
lseek(fd1,0,SEEK_SET);
read(fd1,buff,len/2);//读取1.txt上半内容,存入buff
fd2=open("./2.txt",O_WRONLY | O_CREAT ,0664);
if(fd2==-1)
{
perror("open");
close(fd2);
return -1;
}
write(fd2,buff,len/2);//将buff的内容写入2.txt
printf("上文拷贝成功\n");
close(fd1);
close(fd2);
}
int down_text()
{
int fd1,fd2;
char buff[1024];
int len;
fd1=open("./1.txt",O_RDONLY);
if(fd1==-1)
{
perror("open");
return -1;
}
len=lseek(fd1,0,SEEK_END);
if(len==-1)
{
printf("拷贝失败\n");
}
lseek(fd1,len/2,SEEK_SET);
read(fd1,buff,len/2);//读取1.txt 下半内容,存入buff
fd2=open("./2.txt",O_WRONLY | O_CREAT ,0664);
if(fd2==-1)
{
perror("open");
return -1;
}
lseek(fd2,len/2,SEEK_SET);
write(fd2,buff,len/2);//将buff的内容写入2.txt
printf("下文拷贝成功\n");
close(fd1);
close(fd2);
}
int main(int argc, const char *argv[])
{
pid_t pid;
pid = fork();
if(pid==0)//第一子进程
{
up_text();
exit(EXIT_SUCCESS);
}
else if(pid>0)
{
pid_t pid2;
pid2 = fork();
if(pid2==0)//第二子进程
{
sleep(1);
down_text();
exit(EXIT_SUCCESS);
}
else if(pid2>0)//父进程
{
wait(NULL);
wait(NULL);
exit(EXIT_SUCCESS);//父进程退出
}
}
else
{
perror("fork");
return -1;
}
return 0;
}