赞
踩
程序是存储在磁盘介质上的编译过的二进制文件
进程是程序跑起来的状态
程序是死的,进程是活的
进程是正在执行的程序的一个实例
malloc函数从内存的堆中分配储存
静态变量(通常是所说的程序中的全局变量)会使得线程化的程序不安全,除非保证各个线程访问时是互斥的!!
pid每个进程都有一个id和一个父进程id
获取进程pid/father pid getpid/getppid
就绪的进程就是非阻塞的
阻塞态不会直接去运行
阻塞时不会占用cpu
进程可以通过调用fork函数来创建,调用进程称为父进程
fork函数会复制父进程的内存映像,新进程会收到父进程地址空间的一份copy
fork函数在子进程中返回0
#include<stdio.h> #include<unistd.h> int main(){ int pid; printf("before fork()...\n"); if((pid = fork()) < 0) perror("fork"); if(pid == 0) printf("In child\n"); else{ sleep(1); printf("In parent\n"); } printf("end fork\n"); return 0; }
#include<stdio.h> #include<unistd.h> int main(){ int pid; printf("before fork()..."); if((pid = fork()) < 0) perror("fork"); if(pid == 0) printf("\nIn child\n"); else{ sleep(1); printf("\nIn parent\n"); } printf("end fork\n"); return 0; }
为什么before fork()…输出了两次??
printf()底层是write实现的,行缓冲,当进行到程序的第6行时没有换行
当程序将数据提交给内核时,内核没有看到换行会以为后面还有数据(行缓冲优化)
fork()之后,两个进程的输出缓冲区都有befoe fork,当两个进程的输出缓冲区都读入到换行时进行输出
创建10个子进程
#include<stdio.h> #include<unistd.h> #include<stdlib.h> int main(){ int pid, x; for(int i = 1; i <= 10; i++){ if((pid = fork()) < 0){ perror("fork"); continue; } if(pid == 0){ x = i; break; } } printf("x = %d\n", x); sleep(1); return 0; }
wait函数等待某进程结束
父进程可以通过wait函数一直阻塞到子进程结束
wait(NULL)可以等待当前进程任意一个子进程结束
#include<stdio.h> #include<unistd.h> #include<sys/wait.h> int main(){ int pid; printf("before fork()...\n"); if((pid = fork()) < 0) perror("fork"); if(pid == 0) printf("In child\n"); else{ wait(NULL); printf("In parent\n"); } printf("end fork\n"); return 0; }
#include<stdio.h> #include<unistd.h> #include<sys/wait.h> int main(){ int pid; for(int i = 1; i <= 5; i++){ if((pid = fork()) < 0) perror("fork"); if(pid == 0){ printf("I'm a child\n"); return 0; } } //wait(NULL); for(int i = 1; i <= 5; i++){ wait(NULL); } printf("I'm parent\n"); return 0; }
只wait了一次 所有parent不一定最后执行,要wait 5次才行
fork()函数创建了调用程序的一份copy,但很多子程序要求执行不同的代码,exec函数提供了新映像覆盖调用进程映像的功能
The exec() family of functions replaces the current process image with a new process image.
用fork-exec方法使子进程执行新程序,父进程执行原程序
#include<stdio.h> #include<unistd.h> #include<sys/wait.h> int main(){ int pid; if((pid = fork()) < 0) perror("fork"); if(pid == 0){ execl("/bin/ls", "ls", "-l", NULL);//之后的程序子进程就没有了 execl已经替换了 perror("child failed to exec ls"); return 1; } wait(NULL); return 0; }
git commit不加-m选项时:
fork()一个子进程,子进程打开一个vim 保存退出后 父进程读取刚刚写的命令继续执行后续命令
task:a.out a.c
打开a.c文件(没有的话创建一个),编辑保存退出后编译这个文件,编译成功后执行,最后退出
************************************************************************/ //task:a.out a.c //打开a.c文件(没有的话创建一个),编辑保存退出后编译这个文件,编译成功后执行,最后退出 #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> #include<sys/wait.h> int main(int argc, char **argv){ pid_t pid; char filename[512] = {0}; char o_name[512] = {0};//编译后的文件名称 char f_type[256] = {0}; char cmd[512] = {0}; if(argc < 2){ fprintf(stderr, "Usage: %s filename arg...\n", argv[0]); return 1; } strcpy(filename, argv[1]); char *sub = NULL;//找到.的位置 逆序找到最后一个. if((sub = strrchr(filename, '.')) == NULL){ fprintf(stderr, "Not support File type!\n"); return 2; } strncpy(o_name, filename, sub - filename); strcpy(f_type, sub); if(!strcmp(f_type, ".c")){ strcpy(cmd, "gcc"); }else if(!strcmp(f_type, ".cpp")){ strcpy(cmd, "g++"); }else{ fprintf(stderr, "Not support File type\n"); return 2; } if((pid = fork()) < 0){ perror("fork"); return 3; } if(pid == 0){ execlp("vim", "vim", filename, NULL); } wait(NULL); if((pid = fork()) < 0){ perror("fork"); return 3; } if(pid == 0){ execlp(cmd, cmd, filename, "-o", o_name, NULL); } int status; wait(&status); //status = 0表示子进程执行成功 if(status == 0){ char exe_cmd[50] = {0}; sprintf(exe_cmd, "./%s", o_name); execlp(exe_cmd, o_name, NULL);//./a.out }else{ printf("compile Failed!\n"); return 4; } return 0; }
https://www.cnblogs.com/mickole/p/3187409.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。