Linux操作系统初探(一)

本文介绍了Linux系统的基础知识,包括文件系统结构、shell命令使用方法及通配符,重点讲解了fork函数如何用于创建子进程及其工作原理,并通过实例展示了如何通过fork函数的返回值来区分父进程和子进程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Linux系统中的层次结构

  Linux系统的结构如下图所示:

2. shell

  shell只是一个普通用户程序,它仅仅需要从键盘读取数据,向显示器输出数据和运行其他程序的能力。

   当shell被启动时,它初始化自己,然后在屏幕上输出一个提示符(prompt),并等待用户输入命令行。
   用户输入一个命令行后,shell提取其中的第一个字,嘉定这个字是将要运行程序的程序名,搜索这个程序,如果找到了这个程序就运行它。然后,shell会将自己挂起直到该程序运行完毕,之后再尝试读入下一条命令。

   shell常用的一些命令:
   1. cp src dest  复制文件
   2. head -x file   标准输出文件file的前x行('-'所带的参数是可选的)
   3. ls *.c   列出所有以.c结尾的文件名 
       通配符:* 可以匹配所有的字符    [xyz]表示其中的任意一个
   4. sort <in >out 对in文件的输入,按照字母顺序排序,输出到out中
        其中'<'加上一个紧接着的输入文件名,表示对标准输入进行重定位的语法;
        '>'加上一个紧接着的输出文件名,表示对标准输出进行重定位的语法
     5. 管道符——'|'(pipe symbol):
        linux通过管道符提供了一组各负责一项任务的基本单元(一些过滤器)
        和一个几乎可以用无穷的方式将它们组合起来的机制。
        grep ter*.t|sort|head -20|tail -5 >foo
        //这里所有以.t结尾的文件中包含"ter"的行被写到标准输出中,然后被排序。这些内容的前20行被head选择出来传给tail,它又将后最后5行(也就是排完序的列表中的第16~20行)传给foo。
     6. wc -l <a >b &  字数统计程序wc,用来将文件a中的行数(-l参数确定),并将结果输出到b中。 &表示后台运行
-----------------------------------------------------------------------------------------------
    Linux常见的应用程序:
         cat: 将多个文件连接到标准输出
         chmod:修改文件保护模式
         cp:复制一个或多个文件
         cut:从一个文件中剪切一段文字
         grep:从文件中检索给定模式
         ls:列出目录
         head:提取文件的前几行
         make:编译文件生成二进制文件
         mkdir:创建目录
         od:以八进制显示一个文件
         paste:将一段文字粘贴到一个文件中
         pr:为打印格式化文件
         ps:列出正在运行的进程
         rm:删除一个或多个文件
         rmdir:删除一个目录
         sort:对文件中的所有行按照字母序进行排序
         tail:提取文件的最后几行
         tr:在字符集之间转换
-----------------------------------------------------------------------------------------------

3. fork函数(创建进程)

  在Linux系统中,系统调用fork将会创建一个与原始进程完全相同的进程副本。调用fork函数的进程称为父进程,新的进程称为子进程

   父进程和子进程: 拥有自己的私有内存映像,所以其中一个进程(如父进程)作的修改对另一个进程(子进程)是不可见的。但值得注意的是父进程和子进程可以共享已经打开的文件。也就是说,如果某一个文件在父进程调用fork函数之前就已经打开了,那么在父进程调用fork函数之后,对于父进程和子进程而言,这些修改都是可见的。
   如何区分父子进程?
   fork函数调用给子进程返回一个0值,而给父进程返回一个非零值,这个非零值是子进程的进程标识符(Process Identifier,PID)。两个进程检查fork函数的返回值,并根据返回值继续执行:
  

pid=fork(); //如果创建成功,则父进程pid>0
if(pid < 0){
    handle_error(); //创建失败(比如内存或某些表溢出)
}else if(pid > 0){
    /*这里是父进程的代码*/
}else{
    /*这里是子进程的代码*/
}

  一个进程可以通过getpid获得自己的PID,子进程还可以通过getppid获得其父进程的PID。
有关fork的面试要点
题目:
   

#include <stdio.h>
int main(){
    fork();   //(1)
    fork()&fork()||fork();    //(2)
    fork();   //(3)
}

问题:加上main,总共产生了多少个进程?

  首先需要明确的是:(1)经过fork函数之后,一个进程会作为父进程,产生一个子进程,这个子进程执行fork函数之后的语句;(2)&& 和 || 都有短路操作:A&&B,如果A为假,就不会再去执行B的表达式;A||B如果A为真,则不会去执行B的表达式。
  看这道题:首先,在第一个fork语句(1)执行结束后,main进程会产生一个子进程,我们将main进程和其创建的子进程分别表示为P1和P2,接下来两个进程都会执行(2)(3)两个语句,我们只考虑P1。
  

  不难看出,由于有||和&&的短路特性,所以经过程序段(2)后,P1进程连同自己一共产生了5个进程。同理P2进程连同自己也会产生5个进程。此时程序共有10个进程。接着执行程序语句(3),这10个进程会进一步产生子进程,综上,总共会有10x2=20个进程。

fork的题目其实不难理解,关键是要知道父进程和子进程:哪些部分不同(通常是fork函数的返回值用来作考点的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值