一、程序

  程序(program)是存放在磁盘上、处于某个目录中的一个可执行文件。使用6个exec函数中的一个由内核将程序读入存储器,并使其执行。

二、进程和进程ID

  程序的执行实例被称为进程(process)。某些操作系统使用任务(task)表示正在执行的程序。

  UNIX系统确保每个进程都有一个唯一的数字标识符,称为进程ID(process ID)。进程ID总是一个非负整数。

  程序清单1-4 打印进程ID

  1. [root@localhost unix_env_advance_prog]# cat prog1-.c
  2. #include "apue.h"
  3.  
  4. int
  5. main(void)
  6. {
  7. printf("hello world from process ID %d\n", getpid());
  8. exit();
  9. }

  编译后运行:

  1. [root@localhost unix_env_advance_prog]# ./prog1-
  2. hello world from process ID
  3. [root@localhost unix_env_advance_prog]# ./prog1-
  4. hello world from process ID

  此程序运行时,它调用函数getpid得到其进程ID。

三、进程控制

  有三个用于进程控制的主要函数:fork、exec和waitpid。(exec有六种变体,但经常把它们统称为exec函数。)

  程序清单1-5 从标准输入读入命令并执行(类shell程序的简化实现):

  1. [root@localhost unix_env_advance_prog]# cat prog1-.c
  2. #include "apue.h"
  3. #include <sys/wait.h>
  4.  
  5. int
  6. main(void)
  7. {
  8. char buf[MAXLINE]; /* from apue.h */
  9. pid_t pid;
  10. int status;
  11.  
  12. printf("%% "); /* print prompt (printf requires %% to print %) */
  13. while(fgets(buf, MAXLINE, stdin) != NULL)
  14. {
  15. if(buf[strlen(buf) - ] == '\n')
  16. buf[strlen(buf) - ] = ; /* replace newline with null */
  17.  
  18. if((pid = fork()) < )
  19. {
  20. err_sys("fork error");
  21. }
  22. else if(pid == ) /* child */
  23. {
  24. execlp(buf, buf, (char *));
  25. err_ret("couldn't execute: %s", buf);
  26. exit();
  27. }
  28.  
  29. /* parent */
  30. if((pid = waitpid(pid, &status, )) < )
  31. err_sys("waitpid error");
  32. printf("%% ");
  33. }
  34. exit();
  35. }

  编译后运行:

  1. [root@localhost unix_env_advance_prog]# ./prog1-
  2. % ls
  3. apue.h Makefile prog1-.c prog1-.c prog1-.c prog1-.c prog1-.c
  4. error.c prog1- prog1- prog1- prog1- prog1-
  5. %

  用标准I/O函数fgets从标准输入一次读一行,当键入文件结束符(通常是Ctrl+D)作为行的第1个字符时,fgets返回一个null指针,于是终止循环,进程也就终止。

  因为fgets返回的每一行都以换行符终止,后随一个null字节,故用标准C函数strlen计算此字符串的长度,然后用一个null字节替换换行符。这样做是因为execlp函数要求参数以null而不是以换行符结束。

  调用fork创建一个新进程。新进程是调用进程的复制品,我们称调用进程为父进程,新创建的进程为子进程。fork向父进程返回新子进程的进程ID(非负),对子进程则返回0。因为fork创建一个新进程,所以说它被调用一次(由父进程),但返回两次(分别在父进程及子进程中)。

  在子进程中,调用execlp以执行从标准输入读入的命令。这就用新的程序文件替换了子进程原先执行的程序文件。fork和跟随其后的exec两者的组合是某些操作系统所称道产生(spawn)一个新进程。在UNIX系统中,这两个部分相互分隔,构成两个函数。

  子进程调用execlp执行新程序文件,而父进程希望等待子进程终止,这一要求由调用waitpid实现,其参数指定要等待的进程(在这里,pid参数是子进程ID)。waitpid函数返回子进程的终止状态(status变量)。如果需要,可以使用status变量的值准确地判定子进程是因何终止的。

  小知识:^D表示一个控制字符。控制字符是特殊字符,其形成方法是:在键盘上按下控制键——通常被标记为Control或Ctrl,同时按另一个键。Control-D或^D是默认的文件结束符。

四、线程和线程ID

  通常,一个进程只有一个控制线程(thread),同一时刻只执行一组机器指令。对于某些问题,如果不同部分各使用一个控制线程,那么整个问题解决起来就容易很多。另外,多个控制线程也能充分利用多处理器系统的并行性。

  在一个进程内的所有线程共享同一地址空间、文件描述符、栈以及与进程相关的属性。因为它们能访问同一存储区,所以各线程在访问共享数据时需要采取同步措施以避免不一致性。

  与进程相同,线程也用ID标识。但是,线程ID只在它所属进程内起作用。一个进程中的线程ID在另一个进程中并无意义。当在一个进程中对多个线程进行操作时,我们用线程ID引用相应的线程。

  控制线程的函数与控制进程的函数类似,但另有一套。在进程模型建立很久之后,线程模型才被引入到UNIX系统中,这两个模型之间存在复杂的相互作用。

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

UNIX基础知识之程序和进程的更多相关文章

  1. UNIX环境高级编程--第一章 UNIX基础知识

    第一章 UNIX基础知识 1.2 UNIX体系结构   从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.我们将这种软件称为内核(kernel),因为 它相对较小,且 ...

  2. 《UNIX环境高级编程》(APUE) 笔记第一章 - UNIX基础知识

    1 - UNIX基础知识 Github 地址 1. 操作系统 可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境.通常将这种软件称为 内核 (kernel) .( Linux 是 GN ...

  3. 《UNIX环境高级编程》笔记——1.UNIX基础知识

    这一章节侧重一些基本概念和书中用到的一些名词. 一.引言 所有的操作都提供服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储区以及获得当前时间等. 二.UNIX体系结构 其实linux常见 ...

  4. UNIX环境高级编程 第1章 UNIX基础知识

    所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储空间.提供时间等. UNIX体系结构 严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程 ...

  5. UNIX 基础知识

    登陆       1.登录名            系统在其 口令文件(通常是/etc/passwd文件) 中查看用户名,口令文件中包含了有关用户的信息.       2.shell          ...

  6. APUE(1)----UNIX基础知识

    一.UNIX体系结构 所有操作系统都为他们所运行的程序提供服务,典型的服务包括:执行新程序.打开文件.读文件.分配存储区等.严格意义上来说,操作系统可以定义为一种软件,它控制计算机硬件资源,提供程序运 ...

  7. 第一章 UNIX 基础知识

    1.1 Unix体系结构 OS定义为一种软件,它控制计算机硬件资源,提供程序运行环境,一般称其为内核(kernel),它体积小,位于环境中心. 内核的接口为系统调用(system call),共用函数 ...

  8. apue学习笔记(第一章UNIX基础知识)

    总所周知,UNIX环境高级编程是一本很经典的书,之前我粗略的看了一遍,感觉理解得不够深入. 听说写博客可以提高自己的水平,因此趁着这个机会我想把它重新看一遍,并把每一章的笔记写在博客里面. 我学习的时 ...

  9. APUE 学习笔记(一) Unix基础知识

    1. Unix 体系结构   内核的接口被称为系统调用 公用函数库构建在系统调用接口之上 应用软件既可以调用公用函数库,也可以直接进行系统调用   2. 文件和目录 目录操作函数:opendir--- ...

随机推荐

  1. LoadRunner检查点实战

    码农博客 即将到期,现将博客中部分文章转载到博客园.转载时略有删减. 一.为什么要使用检查点 为什么要使用检查点,那就要说明一下LR如何判断脚本是否执行成功. LR判断脚本是否执行成功是根据服务器返回 ...

  2. Oracle11g导入*.dmp数据文件

    imp命令导入数据:imp username/password@SID file=XXX.dmp fromuser=XXX touser=XXX tables=(XXX,XXX)  [ignore=y ...

  3. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  4. 未能加载Connector/NET :: v6.7.4

    //从*.config文件获取连接字符串和提供程序 string dp = ConfigurationManager.AppSettings["provider"]; string ...

  5. Spark编程实现SQL查询的实例

    1.Oracle中的SQL select count(1) from a_V_PWYZL_CUSTACCT_PSMIS t where not exists (select 1 from tb_sho ...

  6. 运行时环境(The Runtime Environment)

    App Engine应用响应网络请求.当一个客户端(典型的是用户的Web浏览器)使用HTTP请求(比如获取在URL上的网页)连接上应用的时候,网络请求就开始了.当App Engine接收到请求时,它会 ...

  7. Java多线程编程模式实战指南:Active Object模式(上)

    Active Object模式简介 Active Object模式是一种异步编程模式.它通过对方法的调用与方法的执行进行解耦来提高并发性.若以任务的概念来说,Active Object模式的核心则是它 ...

  8. 【转】Nginx系列(四)--工作原理

    原博文出于:    http://blog.csdn.net/liutengteng130/article/details/46724081  感谢! 上篇文章介绍了Nginx框架的设计之管理进程以及 ...

  9. 【转】构建maven web项目

    Maven Web应用 创建Web应用程序 要创建一个简单的java web应用程序,我们将使用Maven的原型 - web应用插件.因此,让我们打开命令控制台,进入到C: MVN目录并执行以下命令m ...

  10. 使用C#读取XML节点,修改XML节点

    例子: <add key="IsEmptyDGAddRootText" value="" /> <!--是否可以修改归档状态档案 false: ...