第一章 第五节

进程与控制

该小节比较粗略的阐述了unix操作系统中用于进程控制的三个函数,分别为 : fork , exec, waitpid, 其中 exec 有五种变体, 这些变体实现的功能全部相同,只是参数不相同而已,他们统称为__exec__函数。

API

#include<unistd.h>
#include<sys/types.h>
pid_t fork(void);

pid是一个宏定义,根据平台不同而不同,大多数情况都是一个int,该函数的难点在与对进程的理解,因为该函数会创建一个进程,创建进程以后,当前的调用进程会“分叉”, 所以该函数会在父进程与子进程中分别返回不同的值, fork 成功之后会获得父进程空间的数据,堆栈资源的副本,就是深拷贝的数据副本,2个进程同时独自享有这些资源,在fork成功之后,我们无法得知子进程与父进程的运行的先后顺序,这依赖于具体实现,虽然进程创建成功之后有了2个“同时”运行的进程, 但是我们的代码是只有一份(其实是2份,但是运行的效果是相同的,无法分别),所以就出现了这种情况:

if(pid<0)
{
fprintf(stderr,"错误!");
}
elseif(pid==0)
{
printf(" child running");
exit(0);
}
else
{
printf("father running and child is : %d\n",pid);
}

我们在程序中可以判断到底是哪个进程在运行,同时根据不同的进程采取不同的运行路径,为什么一段代码可以被2个进程执行呢,因为2个进程拥有相同的资源。即上面的代码其实是2个进程同时运行的(同时运行相同的代码,不是真的2个进程在运行同一段代码),只是看起来像是只有一个进程而已。

exec 系列函数

<unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]);

其中只有execve是真正的api,其他的函数都是对此函数的封装,为了实现方便快捷的调用而已。该函数首先查找要执行的文件,第一个参数可以是文件路径和文件名,也可以只是文件名。函数不同,参数不同,不过大致都是可执行文件的位置,其中第二个参数必须是可执行文件的 文件名, 可以存在于arg[0], 或者是arg0 , 总之都要是文件名, 往后的参数都是该命令的参数,该函数参数列表的结尾部分 必须是NULL, 不管是字符指针数组还是单独的若干个字符数组,其最后的一项必须为NULL。

该函数会替换当前正在执行进程本身,意思就是说当该函数执行成功,当前进程就会变成该函数启动的进程,并且调用进程会停止运行,当exec的进程执行完毕之后,调用进程也不会继续执行,因为它不是被挂起了,而是被替换掉了。

#include<sys/types.h>

#include<sys/wait.h>
pid_t waitpid(pid_t pid,int * status,int options);

该函数用来监控进程状态,第一个参数是目标进程pid,第二个参数是进程状态返回地址,可选参数提供了多种可选方案。

参数pid也可以有别的可选值:

pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。
pid=-1 等待任何子进程,相当于 wait()。
pid=0 等待进程组识别码与目前进程相同的任何子进程。
pid>0 等待任何子进程识别码为 pid 的子进程。

可选参数含义如下,摘选自百度百科

WNOHANG 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若结束,则返回该子进程的ID。

WUNTRACED 若子进程进入暂停状态,则马上返回,但子进程的结束状态不予以理会。

WIFSTOPPED(status)宏确定返回值是否对应与一个暂停子进程。

子进程的结束状态返回后存于 status,下面有几个宏可判别结束情况:

WIFEXITED(status)如果若为正常结束子进程返回的状态,则为真;对于这种情况可执行WEXITSTATUS(status),取子进程传给exit或_eixt的低8位。

WEXITSTATUS(status)取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。

WIFSIGNALED(status)若为异常结束子进程返回的状态,则为真;对于这种情况可执行WTERMSIG(status),取使子进程结束的信号编号。

WTERMSIG(status) 取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。

WIFSTOPPED(status) 若为当前暂停子进程返回的状态,则为真;对于这种情况可执行WSTOPSIG(status),取使子进程暂停的信号编号。

WSTOPSIG(status) 取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。

如果执行成功返回子进程pid, 失败则返回-1, 错误识别码在 errno 中。

该节的例子程序

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> #define MAXLINE 255 char ** string_split(char*, char*);
int parse_cmd(char*); char **
string_split(char * str, char * split)
{
char ** ret_split = (char **)malloc(sizeof(char * ) * MAXLINE);
char * temp;
temp = strtok(str, split);
int i = 0;
while(temp)
{
*(ret_split + i) = temp;
i++;
temp = strtok(NULL, split);
}
*(ret_split +i) = NULL; return ret_split;
} int
parse_cmd(char * cmd)
{
char ** cmds = string_split(cmd, " ");
int signal = execvp(*(cmds + 0), cmds);
return signal;
} int
main(void)
{
char buf[MAXLINE];
pid_t pid;
int status; printf("%%");
while(fgets(buf, MAXLINE, stdin) != NULL)
{
buf[strlen(buf) - 1] = 0;
if((pid = fork()) < 0)
{
printf("fork error");
}
else if(pid == 0)
{
parse_cmd(buf);
printf("could not execute : %s\n", buf);
exit(127);
}
if((pid = waitpid(pid, &status, 0)) < 0)
{
printf("waitpid error");
}
printf("%d\n", status);
printf("%%"); } exit(0);

}

该程序是书中程序的变种,书中的程序是不能带参数执行命令的,我这里简单的处理了一下参数,这是可独立变异运行的版本,不需要ourhdr.h 头文件的支持。

unix-环境高级编程-读书笔记与习题解答-第三篇的更多相关文章

  1. unix 环境高级编程 读书笔记与习题解答第四篇

    第一章 第六节 第一小节 这一章没有程序设计和API方面的深入学习,而是注重介绍了unix操作系统中的原始数据类型和系统原型函数,错误处理方面的知识. ____unistd.h____ 该文件包含了u ...

  2. unix环境高级编程-读书笔记与习题解答-第一篇

    从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...

  3. unix 环境高级编程-读书笔记与习题解答-第二篇

    第四节 输入与输出 上次的笔记中写到的 open, read, write, lseek 以及close ,都是不带缓存的IO函数,这些函数都使用文件描述符进行工作. 上一篇笔记用到的 read(ST ...

  4. [置顶] 文件和目录(二)--unix环境高级编程读书笔记

    在linux中,文件的相关信息都记录在stat这个结构体中,文件长度是记录在stat的st_size成员中.对于普通文件,其长度可以为0,目录的长度一般为1024的倍数,这与linux文件系统中blo ...

  5. [置顶] 文件io(一)--unix环境高级编程读书笔记

    unix-like(后面以linux为例)系统中的文件操作只需要五个函数就足够了,open.close.read.write以及lseek.这些操作被称为不带缓存的io,这里有必要说一下带缓存和不带缓 ...

  6. unix进程的环境--unix环境高级编程读书笔记

    http://blog.csdn.net/xiaocainiaoshangxiao/article/category/1800937

  7. unix环境高级编程 读书笔记

    1.上班业余时间把书下载下来,第一章读完了,但是程序只能回家运行啦!Fighting!

  8. Unix环境高级编程学习笔记——fcntl

    写这篇文正主要是为了介绍下fcntl,并将我自己在学习过程中的一些理解写下来,不一定那么官方,也有错误,希望指正,共同进步- fcntl: 一个修改一打开文件的性质的函数.基本的格式是 int fcn ...

  9. 《UNIX环境高级编程》笔记--UNIX标准化及实现

    1.UNIX标准化 1.1.ISO C 1989 年后期,C程序设计语言的ANSI(American National Standards Institute) 标准X3. 15 9-1989得到批准 ...

随机推荐

  1. Hadoop Hive概念学习系列之什么是Hive?(一)

    参考  <Hadoop大数据分析与挖掘实战>的在线电子书阅读                   http://yuedu.baidu.com/ebook/d128cf8e33687e21 ...

  2. zoj 2734 Exchange Cards【dfs+剪枝】

    Exchange Cards Time Limit: 2 Seconds      Memory Limit: 65536 KB As a basketball fan, Mike is also f ...

  3. hdoj 2899 Strange fuction【二分求解方程】

    Strange fuction Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. Sublime Text 2/3如何支持中文GBK编码

    Sublime Text默认是只支持UTF8的编码,所以有些时候,当我们打开GBK文件时候,文件内会出先部分的乱码, 在菜单栏选择"Preferences"-->" ...

  5. thinkphp 重定向redirect

    /** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg ...

  6. appium api

    AppiumDriver getAppStrings()      默认系统语言对应的Strings.xml文件内的数据.iOS driver.getAppStrings(Stringlanguage ...

  7. [置顶] IOS 基础入门教程

    IOS 基础入门教程 教程列表: IOS 简介 IOS环境搭建 Objective C 基础知识 创建第一款iPhone应用程序 IOS操作(action)和输出口(Outlet) iOS - 委托( ...

  8. HDU ACM 1025 Constructing Roads In JGShining&#39;s Kingdom-&gt;二分求解LIS+O(NlogN)

    #include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; ...

  9. ARC和非ARC文件混编

    在编程过程中,我们会用到很多各种各样的他人封装的第三方代码,但是有很多第三方都是在非ARC情况下运行的,当你使用第三方编译时出现和下图类似的错误,就说明该第三方是非ARC的,需要进行一些配置. 解决方 ...

  10. Java设计模式03:常用设计模式之单例模式(创建型模式)

    1.  Java之单例模式(Singleton Pattern ) 单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实 ...