博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟着iMX28x开发套件学linux-05
阅读量:5332 次
发布时间:2019-06-14

本文共 2738 字,大约阅读时间需要 9 分钟。

五、linux应用编程之三:进程基本操作

linux是一个多任务多用户的系统,可以同时运行多个程序。进程是正在被运行的程序,一个进程至少由一个或者多个线程组成。程序转变为进程的过程是:shell命令运行程序->系统寻找程序文件->fork()函数创建一个新进程->在新进程中用exec族函数装在main()函数。划重点,fork()建立新进程,exec装在程序。所有新进程在被内核创建时都会分配一个唯一的进程ID(PID),如果这个新进程有父进程的话,还会有父进程ID(PPID)。因为linux系统是多任务系统,而CPU的个数却是限定的,所以某个进程不能一直都在运行,要把CPU处理时间让给其他进程,因而进程有6种状态:不可中断的睡眠状态(D),运行或者准备就绪状态(R),可中断的睡眠状态(S),暂停状态(T),即将退出状态(X),僵尸进程状态(Z)。进程基本操作包括:创建进程,终止进程,用exec族函数加载不同的函数。

创建进程

1) 函数原型 pid_t fork(void);

2) 函数输入 无;

3)  pid_t,成功返回子进程的pid,失败返回-1

4)      pid_t  pid = fork();

5)      创建子进程成功后,父进程和子进程的代码是一样的,而且父进程和子进程都是运行态。唯一不同的是,在子进程中fork()返回的值是0,而父进程中fork()的返回值是子进程的pid,所以在代码中可以用if判断pid的值是否等于0,判断成立的代码段就是子进程要运行的代码段,判断不成立的代码段就是父进程要运行的代码段。

终止进程

1) 函数原型 正常终止void exit(int status);/异常终止abort()函数

2) 函数输入 status,终止状态,正常终止可以写0

3) 

4)      exit(0);

5)   1 return 0;实际上也是调用了exit(0);

6)   2 : 如果子进程终止的时候,父进程没有为其运行wait()函数,则子进程将变成僵尸进程,一直占用系统资源无法终止。所以父进程中一般要加上if(wait(&statue) != pid)来判断子进程是否可以终止,分析statue的状态可以知道是正常终止还是异常终止。wait()函数原型为:pid_t wait(int *status);,意思是等待接收子进程的终止状态,程序会卡在这个函数,知道子进程终止或出错。

exec族函数

调用exec族函数可以调用可执行文件,在子线程中可以调用exec族函数加载另一个程序运行。exec族函数一共有6个函数,作用是一样的,只是使用语法和规则有细微差别。

1) int execl(const char *path, const char *arg, ...);

2) int execlp(const char *file, const char *arg, ...);

3) int execle(const char *path, const char *arg,..., char * const envp[]);

4) int execv(const char *path, char *const argv[]);

5) int execvp(const char *file, char *const argv[]);

6) int execve(const char *path, char *const argv[],char *const envp[]);

因为暂时还没使用过传递环境变量,所以e结尾的两个函数暂时先不用。

观察发现所有函数都是exec开头的,只是后面一位或者两位字母有区别。实际上,后缀有l表示加载程序时以列表(变元)形式输入参数,参数就一次写在括号内,以逗号间隔。而后缀有v表示以指针的形式传递新程序的参数,即所有要输入的参数事先写到一个字符串数组里,然后调用函数的时候再引用字符串数组的指针。显然后缀l和后缀v是互斥的,不可能既是l又是v后缀有p表示调用函数的时候*file参数可以只写文件名而不写路径名,此时系统会从环境变量指定的路径中寻找该文件,如果既写了文件名,又写了路径名,则和没有后缀p一样。下图列举了6个函数的使用范例:

 

应该注意到的是,运行新程序时argv的第一个参数是文件名,argv[1]之后的值才是真正的参数。

综合实例:

在一个程序内创建一个子进程,然后在子进程中调用之前写好的file文件。

 

#include 
#include
#include
int main(){ int statue; pid_t pid; pid = fork(); //creat child process if(pid == 0){ //child process printf("here is child process,my pid = %d\n",getpid()); execl("/mnt/file","file",NULL); exit(-1); } else if(pid > 0){ //parent process printf("here is parent process, my pid = %d\n", getpid()); if(pid != wait(&statue)){ printf("child process exit error\n"); exit(-1); } printf("child process exit succeed\n"); exit(0); } else printf("creat process fault\n"); return -1;}

 

 

 

 

运行结果:

 

 

 

转载于:https://www.cnblogs.com/liangda/p/9911374.html

你可能感兴趣的文章
C# 网页自动填表自动登录 .
查看>>
netfilter 和 iptables
查看>>
洛谷P1005 矩阵取数游戏
查看>>
Django ORM操作
查看>>
2012年最佳30款免费 WordPress 主题
查看>>
在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构
查看>>
HDU-1150 Machine Schedule 二分图匹配
查看>>
单例模式的5种写法
查看>>
安卓问题报告小记(四):Some projects cannot be imported because they already exist in the workspace...
查看>>
显示地图
查看>>
无线通信基础(一):无线网络演进
查看>>
如何在工作中快速成长?阿里资深架构师给工程师的10个简单技巧
查看>>
WebSocket 时时双向数据,前后端(聊天室)
查看>>
关于cocoa 运行时runtime
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
asp.net 写入excel时,不能更新。数据库或对象为只读。
查看>>
linux清空日志文件内容 (转)
查看>>
jsp中对jstl一些标签的引用方式
查看>>
安卓第十三天笔记-服务(Service)
查看>>
Servlet接收JSP参数乱码问题解决办法
查看>>