一、程序

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

二、进程和进程ID

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

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

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

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

  编译后运行:

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

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

三、进程控制

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

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

[root@localhost unix_env_advance_prog]# cat prog1-.c
#include "apue.h"
#include <sys/wait.h> int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status; printf("%% "); /* print prompt (printf requires %% to print %) */
while(fgets(buf, MAXLINE, stdin) != NULL)
{
if(buf[strlen(buf) - ] == '\n')
buf[strlen(buf) - ] = ; /* replace newline with null */ if((pid = fork()) < )
{
err_sys("fork error");
}
else if(pid == ) /* child */
{
execlp(buf, buf, (char *));
err_ret("couldn't execute: %s", buf);
exit();
} /* parent */
if((pid = waitpid(pid, &status, )) < )
err_sys("waitpid error");
printf("%% ");
}
exit();
}

  编译后运行:

[root@localhost unix_env_advance_prog]# ./prog1-
% ls
apue.h Makefile prog1-.c prog1-.c prog1-.c prog1-.c prog1-.c
error.c prog1- prog1- prog1- prog1- prog1-
%

  用标准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. cocos2d CCLayer 触摸相关

    要让一个  CCLayer 能够接受触摸输入  需要进行如下设置: [selfsetTouchEnabled:YES]; cocos2d-x提供了两种触摸事件处理机制, 分别是CCStandardTo ...

  2. schema对象介绍

    1.schema对象简介 数据库schema为一组数据结构的逻辑集合,称之为schema对象,schema对象最贱的为表和索引,schema对象由SQL创建和维护. 一个数据库用户拥有一个用户名和各种 ...

  3. 树-哈夫曼树(Huffman Tree)

    概述 哈夫曼树:树的带权路径长度达到最小. 构造规则 1. 将w1.w2.-,wn看成是有n 棵树的森林(每棵树仅有一个结点): 2. 在森林中选出根结点的权值最小的两棵树进行合并,作为一棵新树的左. ...

  4. Modules-nodejs

    Modules Node有一个简易的模块加载系统.在node中,文件和模块是一一对应的.下面示例是foo.js加载同一目录下的circle.js. foo.js的内容: var circle = re ...

  5. Creating Help Pages for ASP.NET Web API -摘自网络

    When you create a web API, it is often useful to create a help page, so that other developers will k ...

  6. 如何学习java ee

    来看看Sun给出的J2EE 相关技术主要分为几大块. 1. Web Service技术 -  Java API for XML Processing (JAXP) -  Java API for XM ...

  7. Linux上svn服务器的搭建

    安装svn服务器 直接用yum安装,命令如下: #yum install -y subversion 验证是否安装成功. #svnserve --version 创建SVN版本库 在home目录下创建 ...

  8. BestCoder Round #66 (div.2) hdu5592

    GTW likes math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  9. [iOS基础控件 - 6.11.2] - UINavigationController 多控制器 简单使用

    A.概念 1.通常一个app有多个控制器 2.需要对这些控制器进行管理 3.有多个view的时候,用一个父view去管理多个子view 4.控制器管理也是如此,使用给一个父控制器,去控制子控制器   ...

  10. JMS开发(三):JMS消息的确认方式

    这里单独列出来我也是觉得有点必要的,毕竟JMS总体知识点并不多,这点可能被很多人所忽视. 首选定义:消息的确认是指消息接受者接到消息,并做出了对应的处理之后,它将回送一个确认消息. 对于非事务性会话, ...