目录
编辑 执行一条命令并等待命令完成后执行原程序函数 popen()
进程概述
程序和进程的区别
- 程序:存储在磁盘上的某个可执行文件
- 进程:程序被执行后称为进程
命令ps -aux:查看系统中进程状态
进程标识符
每个进程都有唯一的进程标识符,进程ID都是非负整数,大部分为int型,小部分为long int型
- pid_t pid
- 获取当前进程pid:getpid()
- 获取当前进程的父进程pid:getppid()
- 当进程的pid = 0时,该进程成为交换进程,用来进程调度
- 当进程的pid = 1时,该进程成为init进程,用来系统初始化
C语言程序的存储空间分配机制
- 正文:代码段
- 初始化的数据:数据段
- 未初始化的数据:存放没有赋值的数据
- 堆:malloc、calloc等开辟空间的地方
- 栈:保存函数调用时的返回地址以及函数的局部变量开辟空间的地方
进程相关函数
创建进程函数fork()
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int data = 20;
pid_t pid;
printf("current process pid is %d\n",getpid());
pid = fork();//fork之后无法决定父子进程谁先执行,但都会执行相同的代码段\
而且父、子进程对数据段的操作不会相互影响
if(pid == 0){
data += 10;
printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
}else if(pid > 0){
printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
}else{
printf("fork is fail\n");
perror("fork");
exit(-1);
}
printf("data is %d\n",data);
return 0;
}
创建线程的另一个函数vfork()
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int data = 20;
pid_t pid;
printf("current process pid is %d\n",getpid());
pid = vfork();//fork之后无法决定父子进程谁先执行,但都会执行相同的代码段\
而且父、子进程对数据段的操作不会相互影响
if(pid == 0){
data += 10;
printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
}else if(pid > 0){
printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
}else{
printf("fork is fail\n");
perror("fork");
exit(-1);
}
printf("data is %d\n",data);
exit(0);
}
进程退出函数
父进程等待子进程函数wait()
- 父进程比子进程先结束会使子进程成为孤儿进程,当子进程成为孤儿进程后,init进程会收养子进程
- 如果子进程退出时,父进程没有等待子进程退出,子进程就会成为僵尸进程(即该进程一直存储在内存中)
wait()函数返回的宏:
- WIFEXITED(status) 当子进程正常结束时返回为真
- WEXITSTUTAS(status) 当WIFEXITED(status)为真时调用,返回状态码的低8位
- WIFSIGNALED(status) 当子进程异常结束时返回为真
- WTERMSIG(status) 当WIFSOGNALED(status)为真时调用,返回引起终止的信号代码
父进程等待子进程退,子进程退出的状态码6被父进程收集
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
int data = 20;
pid_t pid;
printf("current process pid is %d\n",getpid());
pid = fork();
if(pid == 0){
printf("this is child process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
int cnt = 0;
while(1){
cnt++;
sleep(1);
printf("cnt is %d\n",cnt);
if(cnt == 5){
exit(6);
}
}
}else if(pid > 0){
printf("this is father process,current process pid is %d,fork return pid is %d\n",getpid(),pid);
int state = 0;
wait(&state);
for(int i=0;i<WEXITSTATUS(state);i++){
printf("fataher process collect child process exit state is %d\n",WEXITSTATUS(state));
}
}else{
printf("fork is fail\n");
perror("fork");
exit(-1);
}
return 0;
}
进程等待另一个进程函数waitpid()
让当前进程执行新程序函数exec族函数
父进程等待子进程执行新程序后再继续执行程序,新程序打印调用execl()函数的进程ID
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
pid = vfork();
if(pid == 0){
pid_t childPid;
childPid = getppid();
char *str;
str = (char *)malloc(32*sizeof(char));
sprintf(str,"The process ID calling the new program is %d",childPid);
execl("./newProcedure","newProcedure",str,"jiangxiaoya",NULL);
}else if(pid > 0){
wait(NULL);
printf("child process finished executing the new program\n");
}else{
printf("fork is fail\n");
perror("fork");
exit(-1);
}
return 0;
}
新程序newProcedure.c
执行一条命令并等待命令完成后执行原程序函数system()
调用system函数执行终端命令ls
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
int ret;
ret = system("ls");
if(ret == -1 || ret == 127){
perror("system");
exit(-1);
}
return 0;
}
执行一条命令并等待命令完成后执行原程序函数 popen()
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
char readBuf[1024] = {'\0'};
FILE *fp;
fp = popen("ls", "r");
int readSize = fread(readBuf,1,1024,fp);
int fd = open("./filePopen.txt",O_RDWR|O_CREAT,0600);
write(fd,readBuf,readSize);
return 0;
}