赞
踩
gcc xxx.c -o pro
磁盘中生成pro文件叫做程序ps
指令查看,详细的查看需要配合grep
指令,ps -aux | grep
top
指令查看,类似于win任务管理器Pid=0
:交换进程,作用是进程调度Pid=1
:init进程,作用是系统初始化getpid(
)函数获取自身的进程标识符getppid()
获取父进程的进程标识符假设:进程A创建了进程B
则 A叫做父进程,B叫做子进程,父子进程是相对概念,理解为人类中的父子关系
创建一个子进程,同时将父进程的许多参数复制给子进程int a=fork()
:这段表达式,如果在父进程中a=子进程的pid,如果在子进程中a=0
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid; pid = getpid(); int data=0; while(1){ printf("current process id:%d\n",pid); printf("scanf 1 creat process\n"); scanf("%d",&data); if(data==1){ pid = fork(); if(pid==0){ while(1){ printf("child pid=%d\n",getpid()); sleep(3); } } }else { printf("wait,do nothing"); } } return 0; }
int main() { pid_t pid; pid = getpid(); printf("fork=======\n");//注意这里 int fork_pid = fork(); printf("pid:%d, getpid=%d, fork_pid=%d\n",pid,getpid(),fork_pid); return 0; } int main() { pid_t pid; pid = getpid(); printf("fork=======");//注意这里 int fork_pid = fork(); printf("pid:%d, getpid=%d, fork_pid=%d\n",pid,getpid(),fork_pid); return 0; }
这两段代码的不同之处只是printf("fork=======");
和printf("fork=======\n")
;的区别,但是最后的输出结果是不同的,
printf("fork=======")
printf("fork=======\n")
原因在于(AI真方便)
换句话说当子进程创建后,子进程会从被创建的行开始执行,并不是从第一行开始执行,而子进程创建之后,会将父进程的各种状态复制一遍,包括了缓冲区。由于printf("fork=======")
满足了不刷新缓冲区的条件,所以不会立即刷新缓冲区,所以此时缓冲区内保存着一份fork=======
,当子进程创建后,子进程的缓冲区内也保存了一份来自于父进程的fork=======
,但这两者的缓冲区是独立的,所以才出现了上面输出的不同
exit()
:标准C库,会去先对缓冲区做一些处理再退出_exit()
或者_Exit()
,属于系统调用:不会对缓冲区进行处理
_exit()
和_Exit()
是对exit()
的封装pthread_exit
abort()
ctrl+c
(cancellation)
请求做出响应#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t pid; int data=0; pid = vfork(); if(pid>0){ while(1){ printf("data=%d\n",data); printf("current father pid=%d\n",getpid()); sleep(1); } }else if(pid==0){ while(1){ printf("current chilid printf:pid=%d\n",getpid()); sleep(1); data++; if(data==3){ exit(0); } } } return 0; }
等待3s后,通过命令:ps -aux | grep a.out
查看如下
wait(int* status)
:如果其所有子进程都还在运行,则阻塞
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t pid; int data=0; int status=10; pid = vfork(); if(pid>0){ wait(&status);//阻塞等待 printf("status:%d\n",WEXITSTATUS(status)); while(1){ printf("data=%d\n",data); printf("current father pid=%d\n",getpid()); sleep(1); } }else if(pid==0){ while(1){ printf("current chilid printf:pid=%d\n",getpid()); sleep(1); data++; if(data==3){ exit(100); } } } return 0; }
waitpid(pid_t pid, int* status, int options)
:如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
对于pid参数,其等待的ID可以通过vfork()的返回值得到
int main() { pid_t pid; int data=0; int status=10; pid = fork();//1 //pid=vfork(); if(pid>0){ printf("father vfork_pid=%d\n",pid); waitpid(pid,&status,WNOHANG);//2 printf("status:%d\n",WEXITSTATUS(status)); while(1){ printf("data=%d\n",data); printf("current father pid=%d\n",getpid()); sleep(1); } }else if(pid==0){ while(1){ printf("pid=%d\n",pid); printf("current chilid printf:pid=%d\n",getpid()); sleep(1); data++; if(data==5){ exit(100); } } } return 0; }
如果1处调用的是pid=fork()
,2处调用的是waitpid(pid,&status,WNOHANG);
,那么程序实际上会并行运行,但依然会造成僵死进程,这里我猜测应该是父进程运行到waitpid()时,子进程并没有退出,waitpid()无法收集,运行过去后,子进程运行完毕,但是父进程已经进入了while(),所以子进程变为了僵死进程
如果1处调用的是pid=vfork()
,2处调用的不变,程序实际上并不会并行运行,依然会阻塞运行,但不会造成僵死进程
waitid(idtype_t idtype, id_t id, siginfo_t* infop, int options)
:如果它没有任何子进程,则立即出错返回
父进程如果不等待子进程退出,在子进程之前就结束了自己,此时子进程叫做孤儿进程,Linux避免系统存在过多的孤儿进程,init进程收留孤儿进程,变成孤儿进程的夫进程
//主进程文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid; pid = getpid(); int data=0; while(1){ printf("current process id:%d\n",pid); printf("scanf 1 creat process\n"); scanf("%d",&data); if(data==1){ pid = fork(); if(pid==0){ if(execl("./echoarg","./echoarg","TEST.config",NULL) == -1){ printf("execl failed\n"); perror("why"); } printf("after execl\n"); } }else { printf("wait,do nothing"); } } return 0; }
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int main(int argc,char** argv) { printf("%s\n",argv[0]); printf("%s\n",argv[1]); //read src int fds_src = open(argv[1],O_RDWR); int fds_src_size = lseek(fds_src,0,SEEK_END); //move head lseek(fds_src,0,SEEK_SET); char* buf = (char*)malloc(sizeof(char)*fds_src_size); read(fds_src,buf,fds_src_size); lseek(fds_src,0,SEEK_SET); char* p = strstr(buf,"two="); p=p+strlen("two="); *p='8'; write(fds_src,buf,fds_src_size); close(fds_src); return 0; }
实际上system()要比exec族函数要简单粗暴许多
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { pid_t pid; pid = getpid(); int data=0; while(1){ printf("current process id:%d\n",pid); printf("scanf 1 creat process\n"); scanf("%d",&data); if(data==1){ pid = fork(); if(pid==0){ if(system("./echoarg TEST.config") == -1){ printf("execl failed\n"); perror("why"); } printf("after execl\n"); } }else { printf("wait,do nothing"); } } return 0; }
在system()中只需要这样调用system("./echoarg TEST.config")
=execl("./echoarg","./echoarg","TEST.config",NULL)
FILE *popen(const char *command, const char *type);
:第一个参数是指令,第二个参数是指定是读取还是写入模式。如果是r模式,该函数会将第一个参数的结果放到管道中,然后返回一个流,通过FILE流将数据读取出来
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。