Linux.docx
《Linux.docx》由会员分享,可在线阅读,更多相关《Linux.docx(22页珍藏版)》请在冰豆网上搜索。
Linux
实验一、熟悉linux系统
Linux简介
●简单地说,Linux是一套免费使用和自由传播的类Unix操作系统,它主要用于基于Intelx86系列CPU的计算机上。
这个系统是由全世界各地的成千上万的程序员设计和实现的。
其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。
●Linux以它的高效性和灵活性著称。
它能够在PC计算机上实现全部的Unix特性,具有多任务、多用户的能力。
Linux操作系统软件包不仅包括完整的Linux操作系统,而且还包括了文本编辑器、高级语言编译器等应用软件。
它还包括带有多个窗口管理器的X-Windows图形用户界面,如同我们使用WindowsNT一样,允许我们使用窗口、图标和菜单对系统进行操作。
●Linux之所以受到广大计算机爱好者的喜爱,主要原因有两个,一是它属于自由软件,用户不用支付任何费用就可以获得它和它的源代码,并且可以根据自己的需要对它进行必要的修改,无偿对它使用,无约束地继续传播。
另一个原因是,它具有Unix的全部功能,任何使用Unix操作系统或想要学习Unix操作系统的人都可以从Linux中获益。
Linux基本操作介绍
●进入和退出系统
Linux是一个多用户的操作系统,用户要使用该系统,首先必须登录系统,使用完系统后,必须退出系统。
用户登录系统时,为了使系统能够识别自己,必须输入用户名和密码,经系统验证无误后方能进入系统。
在系统安装过程中可以创建两种帐号:
root--超级用户帐号,使用这个帐号可以在系统中做任何事情。
普通用户--这个帐号供普通用户使用,可以进行有限的操作。
用户登录分两步进行:
第一步,输入用户的登录名,系统根据该登录名来识别用户;第二步,输入用户的口令,该口令是用户自己选择的一个字符串,对其他用户是保密的,是在登录时系统用来辨别真假用户的关键字。
运行远程登录命令
telnet192.168.0.80
用户会在屏幕上看到类似下面的提示:
localhostlogin:
这时输入用户名“xxq”,然后键入回车键。
此时,用户会在屏幕上看到输入口令的提示:
localhostlogin:
xxq
Password:
这时,需要输入口令。
输入口令时,口令不会在屏幕上显示出来。
如果用户输入了错误的口令,就会在屏幕上看到下列信息:
loginincorrect.
这时需要重新输入。
当用户正确地输入用户名和口令后,就能合法地进入系统。
屏幕显示:
[xxq@loclhostxxq]$
此时说明该用户已经登录到系统中,可以进行操作了。
●修改口令
为了更好的保护用户帐号的安全,Linux允许用户随时修改自己的口令,修改口令的命令是passwd,它将提示用户输入旧口令和新口令,之后还要求用户再次确认新口令,以避免用户无意中按错键。
如果用户忘记了口令,可以请系统管理员为自己重新设置一个。
●虚拟控制台
Linux是一个真正的多用户操作系统,这表示它可以同时接受多个用户登录。
Linux还允许一个用户进行多次登录,这是因为Linux和许多版本的UNIX一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统直接相连的监视器和键盘)进行多次登录。
虚拟控制台的选择可以通过按下Alt键和一个功能键来实现,通常使用F1-F6。
例如,用户登录后,按一下Alt-F2键,用户又可以看到"login:
"提示符,说明用户看到了第二个虚拟控制台。
然后只需按Alt-F1键,就可以回到第一个虚拟控制台。
一个新安装的Linux系统允许用户使用Alt-F1到Alt-F6键来访问前六个虚拟控制台。
虚拟控制台可使用户同时在多个控制台上工作,真正感受到Linux系统多用户的特性。
用户可以在某一虚拟控制台上进行的工作尚未结束时,切换到另一虚拟控制台开始另一项工作。
例如,开发软件时,可以在一个控制台上进行编辑,在另一个控制台上进行编译,在第三个控制台上查阅信息。
●退出系统
不论是超级用户,还是普通用户,需要退出系统时,在shell提示符下,键入下列命令即可。
下面以普通用户的退出为例,说明退出系统的过程:
[xxq@loclhostxxq]$exit
文件与目录操作
●显示文件目录命令ls
●改变当前目录命令cd
●建立子目录mkdir
●删除子目录命令rmdir
●删除文件命令rm
●文件改名命令mv
●文件复制命令cp
●显示文件的内容more或者less
●查找文件find
●重定向与管道|
进程管理及作业控制
●启动进程
键入需要运行的程序的程序名,执行一个程序,其实也就是启动了一个进程。
在Linux系统中每个进程都具有一个进程号,用于系统识别和调度进程。
启动一个进程有两个主要途径:
手工启动和调度启动,后者是事先进行设置,根据用户要求自行启动。
手工启动
由用户输入命令,直接启动一个进程便是手工启动进程。
但手工启动进程又可以分为很多种,根据启动的进程类型不同、性质不同,实际结果也不一样,下面分别介绍。
●1.前台启动
这或许是手工启动一个进程的最常用的方式。
一般地,用户键入一个命令,这就已经启动了一个进程,而且是一个前台的进程。
●2.后台启动
直接从后台手工启动一个进程用得比较少一些,除非是该进程甚为耗时,且用户也不急着需要结果的时候。
假设用户要启动一个需要长时间运行的格式化文本文件的进程。
为了不使整个shell在格式化过程中都处于“瘫痪”状态,从后台启动这个进程是明智的选择。
启动后台进程只要在启动的进程后面加上一个“&”字符就可以了。
键入命令以后,出现一个数字,这个数字就是系统为该进程分配的进程号,也称为PID,然后立即显示提示符。
用户可以继续其他工作。
fg使被挂起的进程恢复到前台运行。
进程查看
●who命令
该命令主要用于查看当前在线上的用户情况。
●ps命令
使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。
总之大部分信息都是可以通过执行该命令得到的。
●top命令
top命令和ps命令的基本作用是相同的,显示系统当前的进程和其他状况;但是top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态。
如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。
在线帮助
●主要介绍几个常用的联机帮助命令:
●man命令
通常使用者只要在命令man后,输入想要获取的命令的名称(例如ls),man就会列出一份完整的说明,其内容包括命令语法、各选项的意义以及相关命令等。
●help命令
help命令用于查看所有Shell命令。
用户可以通过该命令寻求Shell命令的用法,只需在所查找的命令后输入help命令,就可以看到所查命令的内容了。
●whereis命令
这个程序的主要功能是寻找一个命令所在的位置。
例如,我们最常用的ls命令,它是在/bin这个目录下的。
如果希望知道某个命令存在哪一个目录下,可以用whereis命令来查询。
全屏幕文本编辑器Vi
介绍Linux上最常用的文本编辑器Vi。
文本编辑器是所有计算机系统中最常使用的一种工具。
用户在使用计算机的时候,往往需要建立自己的文件,无论是一般的文本文件、数据文件,还是编写的源程序文件,这些工作都离不开编辑器。
Vi是Linux系统的第一个全屏幕交互式编辑程序,它从诞生至今一直得到广大用户的青睐,历经数十年仍然是人们主要使用的文本编辑工具,足见其生命力之强,而强大的生命力是其强大的功能带来的。
我们将循序渐进地介绍如何使用Vi来建立、编辑、显示以及处理文件。
Vi不是一个排版程序,它不象Word或WPS那样可以对字体、格式、段落等其他属性进行编排,它只是一个文本编辑程序。
Vi没有菜单,只有命令,且命令繁多。
Vi有三种基本工作模式:
命令行模式、文本输入模式和末行模式。
●1.命令行模式
任何时候,不管用户处于何种模式,只要按一下ESC键,即可使Vi进入命令行模式;我们在shell环境(提示符为$)下输入启动Vi命令,进入编辑器时,也是处于该模式下。
在该模式下,用户可以输入各种合法的Vi命令,用于管理自己的文档。
此时从键盘上输入的任何字符都被当做编辑命令来解释,若输入的字符是合法的Vi命令,则Vi在接受用户命令之后完成相应的动作。
但需注意的是,所输入的命令并不在屏幕上显示出来。
若输入的字符不是Vi的合法命令,Vi会响铃报警。
●2.文本输入模式
在命令模式下输入插入命令i、附加命令a、打开命令o、修改命令c、取代命令r或替换命令s都可以进入文本输入模式。
在该模式下,用户输入的任何字符都被Vi当做文件内容保存起来,并将其显示在屏幕上。
在文本输入过程中,若想回到命令模式下,按Esc键即可。
●3.末行模式
在命令模式下,用户按“:
”键即可进入末行模式下,此时Vi会在显示窗口的最后一行(通常也是屏幕的最后一行)显示一个“:
”作为末行模式的提示符,等待用户输入命令。
多数文件管理命令都是在此模式下执行的(如把编辑缓冲区的内容写到文件中等)。
末行命令执行完后,Vi自动回到命令模式。
vi的基本操作
1.进入vi
在系统提示符号下输入vi及档案名称後即进入vi全萤幕编辑画面,且在命令模式下。
[xxq@loclhostxxq]$vifork.c
2.切换至文本输入模式编辑文件:
在命令模式下可按'i'或'a'或'o'三键进入Insertmode。
3.离开vi及存档:
在命令模式下可按':
'键进入Lastlinemode
:
wfilename(存入指定档案)
:
wq(写入并离开vi)
:
q!
(离开并放弃编辑的档案)
命令模式下功能键简介
1.进入文本输入模式
i:
插入,从目前游标所在之处插入所输入之文字。
a:
增加,目前游标所在之下一个字开始输入文字。
o:
从新的一行行首开始输入文字。
2.移动游标
h、j、k、l:
分别控制游标左、下、上、右移一格。
^b:
往後一页。
^f:
往前一页。
G:
移到档案最後。
0:
移到档案开头。
3.删除
x:
删除一个字元。
#x:
例,3x表删除3个字元。
dd:
删除游标所在之行。
#dd:
例,3dd表删除自游标算起之3行。
4.更改
cw:
更改游标处之字到字尾$处。
c#w:
例,c3w表更改3个字。
5.取代
r:
取代游标处之字元。
6.复制
yw:
拷贝游标处之字到字尾。
yy:
可使光标目前所在位置的行整行复制。
p:
复制(put)到所要之处。
(指令‘yw’与‘p’必须搭配使用。
)
7.跳至指定之行
^g:
列出行号
#G:
例,44G表移动游标至第44行行首。
Linux下C语言编程基础知识
在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器。
通常在gcc后跟一些选项和文件名来使用gcc编译器。
gcc命令的基本用法如下:
:
gcc[options][filenames]
命令行选项指定的操作将在命令行上每个给出的文件上执行。
下面我们以一个实例来说明如何使用gcc编译器。
假设我们有下面一个非常简单的源程序(hello.c):
intmain()
{
printf("HelloLinux!
\n");
}
当你不用任何选项编译一个程序时,gcc将会建立(假定编译成功)一个名为a.out的可执行文件。
例如,下面的命令将在当前目录下产生一个叫a.out的文件:
gcchello.c
你能用-o编译选项来为将产生的可执行文件指定一个文件名来代替a.out。
输入下面的命令:
gcc-ohellohello.c
gcc编译器就会为我们生成一个hello的可执行文件,执行./hello就可以看到程序的输出结果了。
命令行中gcc表示我们是用gcc来编译我们的源程序,-o选项表示我们要求编译器给我们输出的可执行文件名为hello,而hello.c是我们的源程序文件。
gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了。
-o选项我们已经知道了,表示我们要求输出的可执行文件名。
-c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件。
这个选项使用的非常频繁因为它使得编译多个C程序时速度更快并且更易于管理。
-g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息。
如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明。
进程创建等系统调用简介
在Linux中,每个进程在创建时都会被分配一个数据结构,称为进程控制块(ProcessControlBlock,简称PCB)。
PCB中包含了很多重要的信息,供系统调度和进程本身执行使用,其中最重要的莫过于进程ID(processID)了,进程ID也被称作进程标识符,是一个非负的整数,在Linux操作系统中唯一地标志一个进程,其实从进程ID的名字就可以看出,它就是进程的身份证号码,每个人的身份证号码都不会相同,每个进程的进程ID也不会相同。
●getpid
getpid的作用很简单,就是返回当前进程的进程ID,请大家看以下的例子:
/*getpid_test.c*/
#include /*提供函数的定义*/
main()
{
printf("ThecurrentprocessIDis%d\n",getpid());
}
编译并运行程序getpid_test.c:
$gccgetpid_test.c-ogetpid_test
$./getpid_test
ThecurrentprocessIDis1980
●fork
fork系统调用的作用是复制一个进程。
当一个进程调用它,完成后就出现两个几乎一模一样的进程,我们也由此得到了一个新进程。
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1.在父进程中,fork返回新创建子进程的进程ID;
2.在子进程中,fork返回0;
3.如果出现错误,fork返回一个负值;
fork出错可能有两种原因:
(1)当前的进程数已经达到了系统规定的上限;
(2)系统内存不足。
下面就让我们通过一个小程序来对它有更多的了解。
/*fork_test.c*/
#include
#inlcude
main()
{
pid_tpid;/*此时仅有一个进程*/
pid=fork();/*此时已经有两个进程在同时运行*/
if(pid<0)
printf("errorinfork!
");
elseif(pid==0)
printf("Iamthechildprocess,myprocessIDis%d\n",getpid());
else
printf("Iamtheparentprocess,myprocessIDis%d\n",getpid());
}
$gccfork_test.c-ofork_test
$./fork_test
Iamtheparentprocess,myprocessIDis1991
Iamthechildprocess,myprocessIDis1992
说到这里,可能有些同学还有疑问:
如果fork后子进程和父进程几乎完全一样,而系统中产生新进程唯一的方法就是fork,那岂不是系统中所有的进程都要一模一样吗?
那我们要执行新的应用程序时候怎么办呢?
●exit
不像fork那么难理解,从exit的名字就能看出,这个系统调用是用来终止一个进程的。
无论在程序中的什么位置,只要执行到exit系统调用,进程就会停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。
请看下面的程序:
/*exit_test1.c*/
#include
main()
{
printf("thisprocesswillexit!
\n");
exit(0);
printf("neverbedisplayed!
\n");
}
编译后运行:
$gccexit_test1.c-oexit_test1
$./exit_test1
thisprocesswillexit!
在一个进程调用了exit之后,该进程并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。
在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。
当一个进程已退出,但其父进程还没有调用系统调用wait(稍后介绍)对其进行收集之前的这段时间里,它会一直保持僵尸状态.
●wait
进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
pid=wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1。
/*zombie.c*/
#include
#include
main()
{
pid_tpid;
pid=fork();
if(pid<0)/*如果出错*/
printf("erroroccurred!
\n");
elseif(pid==0)/*如果是子进程*/
exit(0);
else/*如果是父进程*/
sleep(60);/*休眠60秒,这段时间里,父进程什么也干不了*/
wait(NULL);/*收集僵尸进程*/
}
sleep的作用是让进程休眠指定的秒数,在这60秒内,子进程已经退出,而父进程正忙着睡觉,不可能对它进行收集,这样,我们就能保持子进程60秒的僵尸状态。
编译这个程序:
$cczombie.c-ozombie
后台运行程序,以使我们能够执行下一条命令
$./zombie&
[1]1577
列一下系统内的进程
$ps-ax
......
1177pts/0S0:
00-bash
1577pts/0S0:
00./zombie
1578pts/0Z0:
00[zombie]
1579pts/0R0:
00ps-ax
/*wait1.c*/
#include
#include
#include
#include
main()
{
pid_tpc,pr;
pc=fork();
if(pc<0)/*如果出错*/
printf("errorocurred!
\n");
elseif(pc==0){/*如果是子进程*/
printf("Thisischildprocesswithpidof%d\n",getpid());
sleep(10);/*睡眠10秒钟*/
}
else{/*如果是父进程*/
pr=wait(NULL);/*在这里等待*/
printf("Icatchedachildprocesswithpidof%d\n"),pr);
}
exit(0);
}
编译并运行:
$ccwait1.c-owait1
$./wait1
Thisischildprocesswithpidof1508
Icatchedachildprocesswithpidof1508
可以明显注意到,在第2行结果打印出来前有10秒钟的等待时间,这就是我们设定的让子进程睡眠的时间,只有子进程从睡眠中苏醒过来,它才能正常退出,也就才能被父进程捕捉到。
实验二、进程管理
实验目的
●加深对进程概念的理解,明确进程和程序的区别。
●进一步认识并发执行的实质。
●分析进程争用资源的现象,学习解决进程互斥的方法。
实验预备内容
●复习课本关于进程控制和进程同步的内容,加深对进程管理概念的理解。
●认真阅读以下附录部分,分析多个进程的运行情况,并学会如何解决进程互斥。
实验内容
●运行以下附录部分中给出的程序,查看自己运行的结果,并进行分析。
●编写程序,要求见附录部分
附录:
程序1、
#include"stdio.h"
main()
{inti,j,k;
if(i=fork())
{j=wait();
printf("ParentProcess!
\n");
printf("i=%d,j=%d,k=%d\n",i,j);
}
else
{k=getpid();
printf("ChildProcess!
\n");
printf("i=%d,k=%d\n\n",i,k);
}
}
程序2、
#include
main()
{
intp1,p2;
while((p1=fork())==-1);
if(p1==0)
printf(“b.MyprocessIDis%d”,getpid());
else
{
while((p2=fork())==-1);
if(p2==0)
printf(“c.MyprocessIDis%d”,getpid());
elseprintf(“a.MyprocessIDis%d”,getpid());
}
}
程序3、
main()
{intm,n,k;
m=fork();
printf("PID:
%d\t",getpid());
printf("Thereturnvalueoffork():
%d\t\t",m);
printf("he\n");
n=fork();
printf("PID:
%d\t",getpid());