fork
#include <unistd.h> pid_t fork(void);返回值:
失败返回-1
成功子进程返回0,父进程返回子进程的id
进程调用fork,当控制转移到内核中,内核做如下的事情:
->分配新的内存块和内核数据结构给子进程
->将父进程部分数据结构内容拷贝给子进程
->添加子进程到系统进程列表中
->fork返回,开始调度器调度
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if(pid == -1) { perror("fork"); exit(1); } else if(pid == 0) //child { printf("this is child process!\n"); printf("child pid = %d, father pid = %d\n",getpid(),getppid()); } else //father { printf("this is father process!\n"); printf("father pid = %d\n",getpid()); wait(NULL); } return 0; }fork调用失败的原因:
->系统中已经有太多进程了
->实际用户的进程数超过限制
->平台不支持
system
#include <stdlib.h> int system(const char *command);system()执行通过调用/bin/sh -c命令指定的命令,并在命令完成后返回,在执行命令的时候,SIGCHLD将被阻塞,SIGINT和SIGQUIT将被忽略。
参数:command
命令参数是指向包含shell命令行的以null结尾的字符串的指针。这个命令被传递给/bin/sh使用。
返回值:
fork()失败,返回-1
exec()失败,返回值相当于执行了exit(127)
参数command为NULL,返回1
system()调用bin/sh失败,返回127
成功返回shell的终止状态
popen
#include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream);函数的作用是:通过创建一个管道、forking和调用shell来打开一个进程。由于管道是由定义单向的,类型参数只能指定读或写,而不是两者;生成的流相应地是只读的或只写的.
参数:command
命令参数是指向包含shell命令行的以null结尾的字符串的指针。这个命令被传递给/bin/sh使用。- c标志;解释,如果有的话,是由shell执行的。
type
是一个以NULL结尾的字符串指针, 包含'r'或者'w',在glibc 2.9以后,这个参数还可以包含 'e'
注意:默认情况下,输出popen()流被完全缓冲.
返回值:
如果fork(2)或pipe(2)调用失败,或者无法分配内存,popen()函数将返回NULL。
如果wait4(2)返回一个错误,或者检测到其他错误,那么pclose()函数返回-1。
在发生错误时,这些函数设置errnro来指示错误的原因。
如果内存分配失败,popen()函数不会设置errno。
如果底层的fork(2)或管道(2)失败,errno将被适当地设置。
如果类型参数无效,并且检测到该条件,errno将被设置为EINVAL。
如果pclose()无法获得子状态,则将errno设置为ECHILD。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { FILE* fp; char buf[32]; if((fp = popen("cat aaa.txt","r")) == NULL) { perror("popen"); exit(1); } while(fgets(buf,32,fp) != NULL) { printf("%s",buf); } pclose(fp); return 0; }
