`
jianchen
  • 浏览: 335137 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

unix核心编程原理(四)

阅读更多

                                                                                进程与输入输出重定向

shell是如何运行程序的?
根据用户输入的字符串进行解析后,传给execvp系统函数,启动一个新的进程。比如execvp("ls",arglist)。不过exec(execvp是一组基于execve系统调用函数中的一个,他们统称为exec)系统调用从当前进程中把当前程序的机器指令清除,然后在空的进程中载入调用时指定的代码,最后运行这个新的程序。exec调整进程的内存分配使之适应新的程序对内存的要求。相同的进程,不同的内容。(但值得注意的是,子进程继承了父进程的一些资源,比如打开的文件描述符等,子进程同样可以进行使用。)


显然如果这样做,虽然启动了想执行的进程,当由于是在shell进程空间内执行的,清除了shell的内容,导致shell进程消亡了,如果想执行另一个命令,有需要启动新的shell,这显然达不到我们的要求 。解决方案就是,产生一个不影响shell进程的进程。可以调用系统函数fork(),该函数分配一个新的空间完全复制一个和调用它的进程完全一样的进程,但是新的进程只能从fork()方法之后开始运行。然后再该新进程中调用exec添加要执行的进程。当一个进程调用fork后,就有两个二进制代码完全相同的进程,而且他们都运行到相同的地方。可以通过控制fork()函数的返回值,使得两个进程开始它们自己的旅程。
代码如下:
main(){

int ret_from_fork,mypid;
mypid = getPid();
printf("before:my pid is d%\n",mypid);
ret_from_fork = fork();//该方法返回生成的子进程的进程id号。用于复制出一个进程后,他们都运行到同样的地方,所以父进程中的ret_from_fork的值是id值,而不时初值0,而子进程的ret_from_fork却没有获得值,还是0.通过这样就可以区别两个进程改变两个进程的走向。
switch(ret_from_fork){

case -1:
perror(" fork failed");
exit(1);
//以下就是子进程要执行的代码,他调用exec载入用户输入的命令指定的程序,清除进程空间执行用户指定的程序。
case 0:
execvp(arglist[0],arglist);//arglist[0]中指定用户想执行的命令名。
perror("execvp failed");
exit(1);

default:
while(wait(&exitstatus)!=ret_from_fork);
//shell程序,等待子进程运行结束后,再接受用户输入
}

}

通过以上方法就可以起到一个新的指定进程,而不会影响现在的进程。



输入输出重定向问题:

所有的Unix I/O 重定向都基于标准数据流的原理。
首先讨论重定向到文件:(通常运行的命令都是从标准输入流(键盘)获得程序输入,将执行的结果通过标准输出流打印到显示器上)
三个标准流:标准输入流,标准输出流,标准错误输出流。这三个流的每一种都是一个特别的文件描述符,分别对应:
    0:stdin
    1:stdout
    2:stderr

   
   
Unix假设文件描述符0,1,2都已经打开,可以分别进行读,写操作了。大多数程序并不接收输出文件名,他们总是将结果写到文件描述符1,并将错误消息写到文件描述符2.所以要想将进程的输出写到文件或另一个进程的输入去,就必须重定向相应的文件描述符。可以将文件描述符1指向你想输出的文件,这样就达到了重定向的目的。虽然程序仍然向标准输出写,当却不知道输出的东西已不是留到标准输出了,而是留到了重定向的文件中去了。现在就要考虑如何实现将文件描述符与重定向文件关联起来。在此之前,先让我们了解"最低可用文件描述符"原则:当打开文件时,为此文件安排的描述符总是此数组中最低可用位置的索引。进程并不是从文件读取数据,而是从文件描述符读数据。如果将文件描述符0定位到一个文件,那么此文件就成为标准输入的源。
    有二种方法实现重定位:
    1,close then open
  调用close(0)将标准输入的连接挂断。然后使用open打开一个想连接到的文件。当前的最低可用文件描述符是0,因此所打开的文件将被连接到标准输入上去。
    2,open close dup close
    该方法采用的原理类似,从楼上的电话复制一个连接到楼下,然后就可以在不断线的情况下将楼上的连接切断。
    fd=open(file),获得描述符fd不是0,因为0已经被打开了。
    close(0),将文件描述符0关闭。0现在已经空闲了。
    dup(fd),将文件描述符fd做了一个复制。此次复制使用最低可用文件描述符号,因此获得的文件描述符是0.这样就将磁盘文件与文件描述符0连接在一起了。
    close(fd),关闭文件的原始连接。只留下文件描述符0的连接。


要实现进程之间的I/O重定向,道理差不多,但是要使用管道。将管道的两端与输入输出挂接即可。
当进程创建了一个管道之后,该进程就有了连向管道两端的连接。当这个进程调用fork()的时候,他的子进程也得到了这连个连向管道的连接。父进程和子进程都可以将数据写到管道的写数据端口,并从读数据端口读出。两个进程都可以读写管道,但一个写,一个读,效率是最高的。

分享到:
评论

相关推荐

    UnixLinux 核心编程教程

    Unix/Linux操作系统简介 GNU编译工具GCC GNU C 内存管理 文件I/O 进程管理 信号 进程间通信 多线程 网络通信

    Unix系统编程(程序设计语言+系统调用)

    本课程主要讲述在Unix/Linux环境下高级编程的方法,其内容包括文件、信号、POSIX线程、UDP、WEB和客户机服务器等相关知识,并由浅入深讲述通信、并发和多线程编程的核心技术、实用技术。 前导课程: ①操作系统原理 ...

    UNIX操作系统教程

    《UNIX操作系统教程(第3版)》讲解细致,由浅入深,全面论述了UNIX系统的核心技术与操作系统的基本原理。新版教材更加实用,非常适合作为高等院校计算机及相关专业的操作系统等课程的教材,同时也适合对UNIX系统技术...

    unix大全(涵盖了UNIX学习的方方面面)

    15.SCO UNIX5 的动态核心表 16.进程管理的两个命令(PS,Sar) 评论 17.进程管理的两个命令(PS,Sar) 18.性能相关的几个核心参数(CPU,I/O,MEMORY) 19.SCO NFS详解 20.SCO命令--df 21.SCO OpenServer 5.0.5中DHCP如何...

    UNIX操作系统教程 张红光

    第1章绪论.1 1.1操作系统概述1 1.1.1建立操作系统的目标1 1.1.2操作系统是用户与计算机的接口1 1.1.3操作系统是资源管理器2 1.2UNIX系统的主要特性3 1.3UNIX系统的发展史4 1.4开源软件与UNIX的推广发展6 1.4.1开源...

    网络游戏框架服务端编程

    本书作者以其在韩国多年从事网络游戏开发的经验,向读者展示了网络游戏开发的核心——服务器编程的基本原理和特定技巧。书中首先介绍了计算机网络的基础知识,以及unix socket、winsock编程;然后全面讲述网络游戏...

    Linux系统设计-深入浅出 Linux 操作系统:操作系统原理、Linux 应用实践、并发编程、物联网操作系统

    它继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统,Linux是许多企业和服务提供商的首选操作系统,用于部署Web服务器、数据库服务器、邮件服务器等。Linux系统具有高效的网络功能和稳定的...

    Linux内核工作原理 word版本 强烈推荐

    早期UNIX是用汇编语言编写的,但其第三个版本用一种崭新的编程语言C重新设计了。C是Richie设计出来并用于编写操作系统的程序语言。通过这次重新编写,Unix得以移植到更为强大的 DEC PDP-11/45与11/70计算机上运行。...

    linux操作系统内核技术-uestc课件

     1掌握处理器在进程地址空间上的三种运行位置,了解内核编程不能使用C库函数和FPU,以及可能产生内存故障、核心栈溢出和四种内核竞争情形的原因。(2学时)  2熟悉进程描述符的组织,进程上下文和进程状态转换,和...

    网络编程教程,很好的一本写linux网络编程书,这是我上传的源码

     第四章 基本套接字编程实践  4.1 基本套接字函数族  4.1.1 socket编程的基本流程  4.1.2 函数socket  4.1. 3 函数connect  4.1. 4 函数bind  4.1.5 函数listen  4.1.6 函数accept  ...

    TUXEDO:基于IPC机制浅析TUXEDO及其应用.doc

    本文从底层IPC机制出发,结合UNIX核心系统参数和ATMI技术,借用ipcs观察Tuxedo所消耗的IPC系统资源状况,浅析了Tuxedo强大功能背后的工作原理,进一步加深对Tuxedo应用和ATMI编程的理解,提出了解决实际工作中关键...

    java多线程tcpsocketserver源码-Java-Book:Java学习资料整理

    Unix环境高级编程 --(这三本书主要还是看看Linux下的IO模型,select 和epoll的区别,后面有的框架会涉及到这些内容,比如netty) Unix网络编程 Linux 系统编程手册 Java 基础和进阶 疯狂Java讲义 Java 核心基础卷1/2 ...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    最近几年,他专注于研究Oracle内部原理以及解决性能问题。他的博客主页是 kerryosborne.oracle-guy.com。  ROBYN SANDS 思科公司的软件工程师,为思科的客户设计开发嵌入式Oracle数据库产品。从1996年开始使用...

    开源bbs源码java-Share:分享

    开源 bbs 源码 java 致学弟学妹 & 书单 前言啦 一些自己的积累,不全 希望你们喜欢 ...会不定期更新,欢迎大家补充 ...核心原理与案例分析(推荐) 构建高性能web站点(推荐) 大型网站系统与java中间件

    从零开发操作系统:从加电自检到内核引导

    本门课程是《C语言核心编程》的姊妹篇,正如C和Unix是孪生兄弟一般,本门课程向K?&?R致敬,探索计算机装置的本身原理。本课程基于X86架构,实现了从机器加电自检开始,到一个内建命令操作系统(内核雏形)的实现。...

    redhat linux教材20课程学习文档

    1.4 Linux 与 Unix的比较 1.5 Linux 的发行版本和内核版本 1.6 Linux 的适用场合 1.7 Linux 的未来 第二章 Linux系统基本原理 2.1 Linux的体系结构以图来表现 2.2 基本特点 2.2.1 单核心 2.2.2 多用户的操作系统 ...

    架构解密从分布式到微服务(Leaderus著)

    《架构解密:从分布式到微服务》一开始并没有提及分布式的枯燥理论,而是讲述了一段精彩的IT发展史,其中重点讲述了大型机、UNIX小机器的没落与X86平台的崛起,从而巧妙地引出CPU、内存、网络、存储的分布式演进过程...

    PHP和MySQL WEB开发(第4版)

    11.1 Web数据库架构的工作原理 11.2 从Web查询数据库的基本步骤 11.2.1 检查与过滤用户输入数据 11.2.2 建立一个连接 11.2.3 选择使用的数据库 11.2.4 查询数据库 11.2.5 检索查询结果 11.2.6 从数据库断开连接 ...

Global site tag (gtag.js) - Google Analytics