赞
踩
通过getpid获取当前进程号
sys
pid = 0;交换进程,起着进程调度、资源分配作用
pid = 1;init进程, 系统初始化 譬如界面,
exit():函数exit()“立即”终止调用进程、进程中任何开的文件都被关闭;、进程的任何子进程被进程继承,
wait(&status)等待退出状态、整体长退出用WEXITSTAYUS(status);
waitpid(pid,&status,WNOHANG);//子进程pid,状态值、不挂起WNOHANG
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
-
-
- int main()
- {
- pid_t pid;
- pid_t pid2;
- pid_t retpid;
-
- pid = getpid(); //获取当前pid
- printf("befer pid:%d\n",pid);
-
- retpid = fork(); //把fork的pid返回给retpid 如果大于0 就是当前进程 等于0是子进程
- pid2 = getpid();
- printf("after pid:%d\n",pid2);
- if(pid == pid2){ //第一次的两个pid相等在父进程中,第二次不等在子进程中
- printf("this is father pid:%d,retpid:%d\n",getpid(),retpid);
- }
- else{
- printf("this is child pid:%d,retpid:%d\n",getpid(),retpid);
- }
- return 0;
- }
存储空间分配
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdio.h>
-
- int main()//创建进程不断输入 输入为1 产生一个子进程 父进程什么都不干 让子进程干活
- {
- int data;
- pid_t pid;
-
- while(1){
- printf("qing shu ru data\n");
- scanf("%d",&data);
- if(data == 1){
- pid = fork();
- if(pid > 0){ //父进程
-
- }
- else if(pid == 0){ //子进程不断打印
- while(1){
- printf("this is child pid:%d\n",getpid());
- sleep(2);
- }
- }
- }
- else{
- // printf("shu ru de bu shi 1\n");
- }
- }
-
- return 0;
vfork使用方法,用exit退出、break退出会打乱cnt
- #include <unistd.h>
- #include <stdlib.h>
- #incldue <stdio.h>
-
- int main() //vfork 会先执行子进程 且共用一块内存 会改变数据的值用exit退出 否则破坏cnt值
- {
- pid_t pid;
- int cnt = 0;
- pid = vfork();
-
- if(pid > 0){
- while(1){
- printf("this is the father pid:%d\n",getpid());
- sleep(2);
- printf("this is father cnt:%d\n",cnt);
- }
- }
- else if(pid == 0){ //先执行子进程
- while(1){
- printf("this is the child pid:%d\n",getpid());
- sleep(2);
- cnt++;
- printf("cnt=%d\n",cnt);
- if(cnt == 5){
- exit(-1); //退出子进程 去执行父进程
- }
- }
- }
- return 0;
- }
10中 进程退出:正常、异常退出
正常退出:main中return、调用exit(0)-----标准c库 会对数据处理保存后再退出,
_exif/Exit数据直接退出、线程执行结束---进程结束退出、调用函数pthread_
异常退出:调用abrt、ctel+c、线程取消
进程退出 :使用同一段退出代码,该代码段--是关闭相应进程的 打开描述符。关闭后并释放内存
父进程通过子进程退出的返回状态判断是否正常退出、活做了多少用wait卡住状态 跟vfork有点类似
- //wait等待退出的用法 wait(&status),WEXITSTATUS(status)、exit(5)
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
-
- int main()
- {
- pid_t pid;
- int cnt = 0;
- pid = fork(); //产生一个子进程 用wait等待
- int status = 10; //当status的值和exit退出值相等时说明 子进程正常结束
- // pid_t wait(int *status);
-
- if(pid > 0){ //父进程等待 子进程结束wait取status地址等待
- int num = wait(&status); //wait(null)也等待 但是不关系子进程退出状态
- printf("wait num = %d\n",num); //wait返回值num是子进程的pid号
- printf("fther wait status = %d\n",WEXITSTATUS(status)); //判断status与
- //exit是否相等
- while(1){
- printf("this is the father pid:%d\n",getpid());
- sleep(2);
- }
- }
- else if(pid == 0){
- while(1){
- printf("this is the child pid:%d\n",getpid());
- sleep(2);
- cnt++;
- printf("cnt=%d\n",cnt);
- if(cnt == 5){
- exit(5); //子进程 先执行结束退出 把5传递给wait的status
- }
- }
- }
- return 0;
- }
僵尸进程:父进程不收集子进程退出状态
孤儿进程:子进程还未结束 父进程先结束了
waitpid(pid,&status,WNOHANG);用法和孤儿进程
- //僵尸进程 和孤儿进程
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
-
-
- int main()
- {
- pid_t pid;
- pid = fork();
- int cnt = 0;
- int status = 10;
- // pid_t waitpid(pid_t pid, int *status, int options);
- if(pid > 0){ //子进程还没结束父进程就先结束了
- printf("this is father pid:%d\n",getpid());
- }
- else if(pid == 0){ //子进程
- while(1){ //子进程用getppid打印父进程 第二次之后为1 用init函数收集父进程状态
- //init收留 防止产生更多的孤儿进程
- printf("this is child pid:%d\nfathepid:%d\n",getpid(),getppid());
- cnt++;
- printf("cnt = %d\n",cnt);
- if(cnt == 5){
- exit(5);
- }
- sleep(2);
- }
- }
-
- return 0;
- }
exec族函数:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
- //exex族函数 调用成功直接运行族函数中的可执行文件,不反回,错误返回-1
- //exexl exexlp execvp
- #include <stdio.h>
- #include <unistd.h>
-
- int main()
- {
- // int execl(const char *path, const char *arg, ...);//注意exexl四个参数
- if(execl("./echarg","echarg","aa",NULL) == -1){ //成功直接执行 调用的可执行文件
- printf("exec error!!\n"); //错误返回-1
- perror("why:");
- }
- printf("mei you diao yong chenggong\n");
- return 0;
- }
-
-
-
- int main()
- {
- // int execl(const char *path, const char *arg, ...);
- if(execl("/bin/ps","ps","-aux",NULL) == -1){ //exexl参数(路径、文件名、传参、
- // NULL结尾)
- printf("exec error!!\n");
- perror("why:");
- }
- printf("mei you diao yong chenggong\n");
- return 0;
- }
-
-
- int main()
- {
- // int execl(const char *path, const char *arg, ...);
- if(execlp("date","date",NULL,NULL) == -1){ //exexlp不用加路劲 PATH已近声明
- printf("exec error!!\n");
- perror("why:");
- }
- printf("mei you diao yong chenggong\n");
- return 0;
- }
-
- int main()
- {
- // int execvp(const char *file, char *const argv[]);
- char *argv[] = {"data",NULL,NULL};
- if(execvp("date",argv) == -1){ //execvp两个参数 封装
- printf("exec error!!\n");
- perror("why:");
- }
- printf("mei you diao yong chenggong\n");
- return 0;
- }
-
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[])
int execle(const char *path, const char *arg,..., char * const envp[]);
我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。
返回值:
exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。
参数说明:
path:可执行文件的路径名字
arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录
main函数中fork打开子进程,在子进程中exrcl("./changeData","changeData","test.txt",NULL)
直接写到if里面不够灵活,因为我们只能把子进程的程序代码粘贴过来执行,这样必须知道源代码,太长了也不好控制,比如希望子进程执行ls -a,这样是不行的,因为ls的源代码没有这样ls放在子进程里面就实现不了,
此时就是用exec族函数,可以直接把一个编译好的可执行程序,直接加载运行
- //fork创建子进程 在子进程中用execl函数执行可执行文件
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
- int main()
- {
- pid_t pid;
- int data;
- while(1){
- scanf("%d",&data);//不要加换行
- printf("please input!\n");
-
- if(data == 1){ //输入为1 创建子进程
- pid = fork();
- printf("password");
- if(pid > 0){
- wait(NULL);//只要有等待就不会成为僵尸进程
- }
- else if(pid == 0){ //在子进程中调用changeData函数 传过去txt文件修改
- execl("./changeData","changeData","config.txt",NULL);
-
- }
- }
-
- }
- return 0;
- }
-
- /*
- int main() //execl执行的changeData程序
- {
- int fd;
- char *readBuf;
- fd = open("./config.txt",O_RDWR|O_CREAT,0600);
- int size = lseek(fd,0,SEEK_END);
- lseek(fd,0,SEEK_SET);
- readBuf = (char *)malloc(sizeof(char)*size + 8);
- read(fd,readBuf,size);
-
- char *p = strstr(readBuf,"LENG=");
- if(p == NULL){
- printf("mei zhao dao !\n");
- }
- p = p+strlen("LENG=");
- *p = '5';
- p = p+sizeof(char);
- *p = '5';
-
- lseek(fd,0,SEEK_SET);
- write(fd,readBuf,strlen(readBuf));
- close(fd);
- }
-
- */
system函数使用方法
- #include <stdio.h>
- #include <stdlib.h>
-
- int main()
- { //system和exex函数大致相同
- //成功返回进程pid 不能返回时返回127 失败返回-1
- if(system("ls -l") == -1){ //先执行system函数 结束后 返回继续执行其他
- printf("erro\n");
- perror("why:\n");
- }
- printf("da yin cheng gong\n");
-
- return 0;
- }
popen函数用法
- //pipe exec system一般用于子进程中执行可以执行文件
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int main()
- {
- //pipe是流(只能r/w) 返回文件类型 用fread把里面内容读出来 并打印
- // FILE *popen(const char *command, const char *type);
- FILE *fp;
- char str[1024] = {0}; //用于存放读取文件
- fp = popen("ps -aux|grep ./a.out","r"); //pipo可以获取输出结果 返回文件类型
- // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- int n_fread = fread(str,1,1024,fp); //流 用fread获取内容
- printf("n_read:%d str:%s\n",n_fread,str);//打印
- fclose(fp);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。