网站添加漂浮二维码怎么做,唐山最新消息今天,wordpress柚子皮5.31 .zip,贵安新区城乡住房建设厅网站1.进程的含义?
进程是一个程序执行的过程#xff0c;会去分配内存资源#xff0c;cpu的调度
PID, 进程标识符 当前工作路径 chdir umask 0002 进程打开的文件列表 文件IO中有提到 #xff08;类似于标准输入 标准输出的编号#xff0c;系统给0#xff0c;1#xf…1.进程的含义?
进程是一个程序执行的过程会去分配内存资源cpu的调度
PID, 进程标识符 当前工作路径 chdir umask 0002 进程打开的文件列表 文件IO中有提到 类似于标准输入 标准输出的编号系统给012 标准输入 标准输出 标准错误 信号相关设置 处理异步io
用户id组id 进程资源的上限的命令ulimit -a显示资源上限。
2.进程和程序的区别? (1)程序:静态 存储在硬盘中代码数据的集合 (2)进程:动态 程序执行的过程,包括进程的创建、调度、消亡 .c ---- a.out----- process(pid) 1程序是永存进程是暂时的 2进程有程序状态的变化程序没有 3进程可以并发程序无并发 4进程与进程会存在竞争计算机的资源 5一个程序可以运行多次变成多个进程 一个进程可以运行一个或多个程序 内存的分布 0-3G,是进程的空间3G-4G是内核的空间,虚拟地址 虚拟地址 * 物理内存和虚拟内存的地址 映射表 1page4k mmu
这部分占3G,其他部分是操作系统 进程分类 1、交互式进程 2、批处理进程 shell脚本 3、 守护进程 3.进程的作用? 并发,并行区别。 while (1) { while (1) { 上下左右 发视频 } }
同一时刻完成多个任务4.进程的状态 3个状态就绪→执行态→阻塞等待睡眠基本操作系统 linux中的状态运行态睡眠态僵尸暂停态。5.进程的调度进程上下文切换 内核主要功能之一就是完成进程调度, 硬件biosio文件系统驱动 调度算法 otheridle rrfifo 宏观并行 微观串行6.查询进程相关命令
1.ps aux 查看进程相关信息 1.就绪态、运行态 R 2.睡眠态、等待态 可唤醒等待态 S 不可唤醒等待态 D 3.停止态 T 4.僵尸态 Z 5.结束态2.top 根据CPU占用率查看进程相关信息3.kill和killall发送一个信号kill -2 PID 15 发送信号PID对应的进程默认接收者关闭killall -9 进程名 发送信号 进程名对应的所有进程 killall a.out 原语1.fork(); pid_t fork() 叉子 一次调用会返回两次。 子进程先进行和是父进程先进程顺序不确定。 父与子 的 变量不共享。 子进程复制父进程的0到3g空间和父进程内核中的PCB但id号不同。
但子的id号不是0 功能通过该函数可以从当前进程中克隆一个同名新进程。 克隆的进程称为子进程原有的进程称为 父进程。 子进程是父进程的完全拷贝。 子进程的执行过程是从fork函数之后执行。 子进程与父进程具有相同的代码逻辑。返回值int 类型的数字。 在父进程中成功 返回值是子进程的pid号 0 失败 返回-1 在子进程中成功 返回rrrrrrrrrrrrr值 0 失败 无 面试题 一次fork生成几个进程他们之间的关系是什么样的 如果两次fork同时前后执行会生成几个进程他们之间的 关系如何表示有多少个子进程有没有孙进程2.getpid pid_t getpid(void); 功能: 获得调用该函数进程的pid 参数: 缺省 返回值: 进程的pid pid_t getppid(void); 功能: 获得调用该函数进程的父进程pid号 参数: 缺省 返回值: 返回父进程id号 fork()fork()||fork(); while(1)sleep(1);应用场合 1一个进程希望复制自己使父子进程同时执行同的代码段。网络服务中会比较多见。 2一个进程需要执行一个不同的程序。forkexec7、父子进程的关系 子进程是父进程的副本。子进程获得父进程数据段堆栈正文段共享。 在fork之后一般情况那个会先运行是不确定的。如果非要确定那个要先运行需要IPC机制。 区别 1fork的返回值 2pid不同一般来说子的要比父的大8、进程的终止8种情况 正常结束
1main 中return 2exit() c库函数会执行io库的清理工作关闭所有 的流以及所有打开的文件。已经清理数atexit 。 3_exit,_Exit 会关闭所有的已经打开的文件不执行清理函数。 4) 主线程退出 5主线程调用pthread_exit 异常终止 6abort() 在非常紧急的情况内核调用函数来退出进程 7signal kill pid 8)最后一个线程被pthread_cancle
9.僵尸进程和孤儿进程 危害 孤儿进程Orphan Process
定义 产生原因 特点 僵尸进程Zombie Process 定义 僵尸进程是指一个已经终止、但是其父进程尚未对其进行善后处理的获取终止进程的有关信息释放它仍占用的资源的进程。 产生原因 当子进程比父进程先结束而父进程没有回收子进程释放子进程占用的资源时子进程将成为一个僵尸进程。 特点 僵尸进程不占用除进程表项外的任何系统资源。僵尸进程不能被kill命令杀死因为它已经不存在于活动进程列表中。如果父进程不调用wait或waitpid等函数来回收僵尸进程那么保留的那段信息就不会释放其进程号就会一直被占用。系统所能使用的进程号是有限的如果大量的产生僵尸进程将因为没有可用的进程号而导致系统不能产生新的进程。孤儿进程是指在其父进程执行完成或被终止后仍继续运行的一类进程。当一个父进程由于正常完成工作而退出或由于其他情况被终止而它的一个或多个子进程却还在运行时这些子进程将成为孤儿进程。孤儿进程会被init进程进程号为1所收养并由init进程对它们完成状态收集工作。孤儿进程本身并没有危害因为它们的资源回收工作由init进程负责。
1exit 库函数 退出状态终止的进程会通知父进程自己使如何终止的。如果是正常结束终止则由exit传入的参数。如果是异常终止则有内核通知异常终止原因的状态。任何情况下负进程都能使用waitwaitpid获得这个状态以及资源的回收。
缓冲区里的数据还会被保留 void exit(int status) exit(1); 功能: 让进程退出,并刷新缓存区 参数 status:进程退出的状态 返回值: 缺省
EXIT_SUCCESS 0 EXIT_FAILURE 1
return 当该关键字出现在main函数中时候可以结束进程 如果在其他函数中则表示结束该函数。 exit - 刷新缓存区 - atexit注册的退出函数 - _exit】 2._exit 系统调用 void _exit(int status); 功能: 让进程退出,不刷新缓存区 参数: status:进程退出状态 返回值: 缺省
缓冲区的数据不会被保留 mianint agc,argv { main } //缓冲区//
行缓冲 全缓冲文件
缓冲区大小为4k
出缓冲区的条件少了一个“\n”.
回调函数调用下面的函数时在里填入函数这个函数是进程退出前执行的函数3.atexit int atexit(void (*function)(void));
函数类型不能变化
功能: 注册进程退出前执行的函数资源回收清理函数 参数: function:函数指针 指向void返回值void参数的函数指针 返回值: 成功返回0 失败返回非0
当程序调用exit或者由main函数执行return时,所有用atexit 注册的退出函数,将会由注册时顺序倒序被调用
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
char * tmpNULL;
void clean(void)
{printf(this is clean %s\n,tmp);free(tmp);
}
int main(int argc, char *argv[])
{atexit(clean);tmp (char*) malloc(50);strcpy(tmp,hello);printf(123123\n);return 0;
}4、进程空间的回收
exit(20); 里的数字填入哪个都可以只要不超过127
wait/waitpid
pid_t wait(int *status); 功能该函数可以阻塞等待任意子进程退出 并回收该进程的状态。 一般用于父进程回收子进程状态。
参数status 进程退出时候的状态
返回值成功 回收的子进程pid 失败 -1
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include sys/types.h
#include sys/wait.h
int main(int argc, char *argv[])
{pid_t pid fork();if(pid0){printf(father pid:%d ppid:%d\n,getpid(),getppid());pid_t recycle_pid wait(NULL);printf(recycle pid %d\n,recycle_pid);sleep(10);printf(aaa\n);}else if(0 pid){sleep(3); printf(child pid:%d ppid:%d\n,getpid(),getppid());exit(0);}else {perror(fork);return 1;}return 0;
}
用以下宏来判断status进程退出时的状态
如果不关心其退出状态一般用NULL表示 如果要回收进程退出状态则用WEXITSTATUS回收。
WIFEXITED(status) 是不是正常结束
WEXITSTATUS(status) 使用这个宏去那返回值
WIFSIGNALED(status) 是不是收到了信号而终止的
WTERMSIG(status)如果是信号终止的那么是几号信号。
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include sys/types.h
#include sys/wait.h
int main(int argc, char *argv[])
{pid_t pid fork();if(pid0){//stat(1.txt,st);int status;printf(father pid:%d ppid:%d\n,getpid(),getppid());pid_t recycle_pid wait(status);if(WIFEXITED(status)){printf(child normal terminal,recycle pid %d , exit value %d\n,recycle_pid,WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf(child terminal bu signal ,rrecycle pid %d, signal num %d \n,recycle_pid,WTERMSIG(status));}}else if(0 pid){printf(child pid:%d ppid:%d\n,getpid(),getppid());sleep(5); exit(20);}else {perror(fork);return 1;}return 0;
}
pid_t wait(int *status); 1如果所有的子进程都在运行在阻塞 2如果一个子进程终止正在等待的父进程则获得终止状态获得子进程的状态后立刻返回。 3如果没有子进程则立即出错退出。 waitpid(-1,status,0)wait(status); pid_t waitpid(pid_t pid, int *status, int options); -1 回收指定进程组内的任意子进程 -1 回收任意子进程组内外 0 回收和当前调用waitpid一个组的所有子进程组内 0 回收指定ID的子进程 waitpid (-1,a,0) wait(a); status 子进程退出时候的状态 如果不关注退出状态用NULL options 选项 0 表示回收过程会阻塞等待 WNOHANG 表示非阻塞模式回收资源。 返回值成功 返回接收资源的子进程pid 失败 -1 0, EAGAIN #include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include sys/types.h
#include sys/wait.h
int main(int argc, char *argv[])
{pid_t pid fork();if(pid0){//stat(1.txt,st);int status;printf(father pid:%d ppid:%d\n,getpid(),getppid());while(1){pid_t recycle_pid waitpid(pid,status,WNOHANG );if(recycle_pid pid){if(WIFEXITED(status)){printf(child normal terminal,recycle pid %d , exit value %d\n,recycle_pid,WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf(child terminal bu signal ,rrecycle pid %d, signal num %d \n,recycle_pid,WTERMSIG(status));}break;}else {printf(子进程未结束,稍后在试\n);}}}else if(0 pid){printf(child pid:%d ppid:%d\n,getpid(),getppid());sleep(5); exit(20);}else {perror(fork);return 1;}return 0;
}
练习 设计一个多进程程序用waitpid函数指定回收 其中的某个进程资源并将其状态打印输出。 其他的进程都以非阻塞方式进行资源回收。
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include sys/types.h
#include sys/wait.h
int main(int argc, char *argv[])
{int i 0;pid_t pid[5]{0};for(i0;i5;i){pid[i] fork();if(pid[i]0){continue;}else if(0 pid[i]){printf(child pid:%d ppid:%d\n,getpid(),getppid());sleep(rand()%51); exit(0);}else {perror(fork);return 1;}}int status;while(1){pid_t recycle_pid waitpid(pid[2],status,WNOHANG );if(recycle_pid pid[2]){if(WIFEXITED(status)){printf(child normal terminal,recycle pid %d , exit value %d\n,recycle_pid,WEXITSTATUS(status));}if(WIFSIGNALED(status)){printf(child terminal bu signal ,rrecycle pid %d, signal num %d \n,recycle_pid,WTERMSIG(status));}break;}else {// printf(子进程未结束,稍后在试\n);}}return 0;
}10.execute exec族 用fork创建子进程后执行的是和父进程相同的程序但有可能执行不同的代码分支子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时该进程的 用户空间代码和数据完全被新程序替换从新程序的启动例程开始执行。执行完毕不回原程序调用exec并不创建 新进程所以调用exec前后该进程的id并未改变。 其实有六种以exec开头的函数统称exec函数 vector ls -l -i list execl(/bin/ls,-l,-i,NULL); execlp(ls,-l,-i,NULL); #include unistd.h int execl(const char *path, const char *arg, ...); int execv(const char *path, char *const argv[]);
keyvalue int execle(const char *path, const char *arg, ..., char *const envp[]); int execle(const char *path, const char *arg, ..., char *const envp[]);
int execve(const char*path,char*const argv[],char*const evnp[]); int execlp(const char *file, const char *arg, ...); echo $PATH PATH int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]);
这些函数的区别 1前4个使用路径名作为参数后面两个使用文件名做参数 当filename中含有/时视为路径名否则就按PATH变量在指定目录下查找可执行文件。 2相关的参数表传递 l表示listv表示vector execl,execlp,execle,需要将参数一个一个列出并以NULL结尾。 execvexecvpexecve需要构造一个参数指针数组然后将数组的地址传入。 3以e结尾的函数可以传入一个指向环境字符串的指针数组的指针。其他未指定环境变量使用父进程继承过来的。一般不调用带环境变量的不主动改变环境变量 execve 是真正的系统调用 这些函数如果调用成功则加载新的程序从启动代码开始执行不再返回如果调用出错 则返回-1所以exec函数只有出错的返回值而没有成功的返回值。
char *const ps_argv[] {ps, -o, pid,ppid,pgrp,session,tpgid,comm, NULL}; char *const ps_envp[] {PATH/bin:/usr/bin, TERMconsole, NULL}; execl(/bin/ps, ps, -o, pid,ppid,pgrp,session,tpgid,comm, NULL); execv(/bin/ps, ps_argv); execle(/bin/ps, ps, -o, pid,ppid,pgrp,session,tpgid,comm, NULL, ps_envp); execve(/bin/ps, ps_argv, ps_envp); execlp(ps, ps, -o, pid,ppid,pgrp,session,tpgid,comm, NULL);
execvp(ps, ps_argv);
#include stdio.h
#include unistd.h
int main(int argc, char *argv[])
{// firefox www.taobao.com execl(/usr/bin/firefox,firefox,www.taobao.com,NULL);printf(看见就错了\n);return 0;
}
#includestdio.h
#includeunistd.h
int main(int argc, const char *argv[])
{//execl(/bin/ls,ls,-a,-l,-h,-F,--color,NULL);//p:系统中的环境路径env path能找到execlp(ls,ls,-a,-l,-h,-F,--color,NULL);return 0;
}
#include stdio.h
#include unistd.h
int main(int argc, char *argv[])
{char*const arg[]{ls,-a,-l,-h,-F,--color,NULL};execv(/bin/ls,arg);printf(看见就错了\n);return 0;
}
#include stdio.h
#include unistd.h
int main(int argc, char *argv[])
{char*const arg[]{ls,-a,-l,-h,-F,--color,NULL};execvp(arg[0],arg);printf(看见就错了\n);return 0;
}
在一个程序main中调用文件中另一个程序 1.c #include stdio.h
int main(int argc, char *argv[])
{printf(argc is %d\n,argc);int i 0 ;for(i0;iargc;i){printf(%d %s\n,i,argv[i]);}return 0;
}
#includestdio.h
#includeunistd.h
int main(int argc, const char *argv[])
{execl (/home/linux/cpz/process/cpz,./cpz,1,2,3,4,NULL);return 0;
}