Linux内核与程序设计》实验指导

实验一  实验名称:常用命令和编辑器的使用(2学时)

一、实验目的

1、掌握Linux一般命令格式

2、掌握有关文件和目录操作的常用命令

3、掌握有关进程操作的常用命令

4、熟悉使用man命令

5、学习使用vi编辑器的建立、编辑、显示及加工处理文本文件

二、实验内容

1、熟悉date、cal、who、echo、clear、passwd命令

2、在用户主目录下对文件进行操作:复制一个文件、显示文件内容、查找指定内容、排序、文件比较、文件删除等

3、对目录进行管理:创建和删除子目录、改变和现实工作目录、列出和更改文件权限、链接文件等

4、利用man显示date、echo等命令的手册页

5、利用文本插入方式建立一个文件

6、对该文件执行删除、复原、修改、替换等操作

三、主要实验步骤

1、使用简单命令date、cal、who、echo、clear、passwd等,了解linux命令格式

输入date会显示当前日期

输入cal会显示日历

who:显示用户

clear 清屏

passwd 更换用户密码

2、浏览文件系统:

(1)运行pwd命令,确定当前工作目录

pwd:输出当前目录

(3)运行ls –ai命令,理解各字段含义

ls  :列出当前目录下的文件和文件夹,不包括隐藏文件

ls -l:显示当前目录下文件或者文件夹的详细信息

ls -a:列出当前目录下的文件和文件夹,包括隐藏文件

ls -i:列出当前目录下的文件和文件夹,并显示其index

ls -ai:列出当前目录下的文件和文件夹,包括隐藏文件,并显示其index

(4)使用cd命令,将工作目录改为根(/)上,运行ls –l命令,结合书中图2.2,了解个目录的作用

/表示根目录

cd  /即可

(5)直接使用cd,回到哪里了?用pwd验证

答案是:/home/ysk,即用户目录

(6)用mkdir建立一个子目录subdir

创建子目录:mkdir subdir

(7)将工作目录改到subdir

在 /home/ysk 下输入命令cd subdir

定位为 /home/ysk/subdir

3、工作操作

(1) 验证当前工作目录在subdir

(2) 运行date>file1,然后运行cat file1,看到什么信息?

cat file1 是将file1文件中的内容显示到屏幕上

date>file1 是将当前时间输出入道file1中

(3) 运行cat subdir,会有什么结果?为什么?

cat: subdir: Is a directory

(4) 利用man命令显示date命令的使用说明

man date

4、运行man date>>file1,看到什么?

追加进入file1

运行cat file1,看到什么?

显示 file1 内的内容

5.文件操作

(1)显示file1的前10行,后10行

head -10 file1

tail -10 file1

(2)运行cp file file2,然后ls –l,看到什么

凭空多出了file2呗,内容与file完全相同

(3)运行cat f*,结果怎样

输出f开头文件的内容?

(4)运行rm file3,然后ls –l,结果如何

删了

(5)统计file1文件的行数、字数

cat file1|wc -l

6.vi编辑器

(1)进入vi

(2)建立一个文件,如file.c.进入插入方式,输入一个C语言程序的各行内容,故意制造几处错误.最后,将该文件存盘.回到shell状态下.

(3)运行gcc file.c –o myfile,编译文件,会发现错误提示.理解其含义

(4)重新进入vi,对该文件进行修改.然后存盘,退出vi.重新编译该文件.如果编译通过了,可以用./myfile运行该程序

(5)运行mandate>file10,然后vi file10。

使用x,dd等命令删除某些文本行。

使用u命令复原此前的情况。

使用c、r、s等命令修改文本内容。

使用检索命令进行给定模式的检索。

在vi编辑器中调大字体 ctrl+shift+'+'

在vi编辑器中减小字体 ctrl+'-'

linux退出vi编辑器的方法

对于vi编辑器而言,输入i是插入状态。

如果要退出的话,先按esc键,然后输入冒号(:),

再输入wq是保存且退出,输入q!不保存退出。

在某个一行按 数字+yy 可以复制指定数字的行,然后按p粘贴

u 撤销

ctrl+r 恢复上一步的操作

实验二 实验名称:shell脚本的设计和执行(2学时)

一、实验目的

1.  了解shell的作用和主要分类

2.  掌握shell脚本的建立和执行方式

3.  掌握编写shell脚本的基本语法

4.  学会编写并执行shell脚本

二、实验内容

1.  历史命令和别名定义

2.  shell脚本的建立和执行

3.  shell变量和位置参数、环境变量

4.  shell特殊字符在脚本中的使用

5.  一般控制结构的使用

6.  算数运算和函数的使用

三、主要实验步骤

1.  利用vi编辑器建立一个简单的shell脚本,其中包括date,pwd,ls等常用命令。然后以至少两种不同的方式执行该脚本(参考书上P84,4.1.3节内容)。

[ysk@localhost ~]$ cat aaa

echo hello,world

echo "hello,world2"

[ysk@localhost ~]$ bash

hello,world

hello,world2

[ysk@localhost ~]$

2.  运行history命令,查看历史命令环境;

[ysk@localhost ~]$ history

3.  体会命令补齐功能(参见4.3节内容);

[ysk@192 ~]$ cat ex

ex       ex11~    ex14     ex2      ex4      exam12~  exp1

ex~      ex12     ex17     ex2~     ex4~     exam13

ex11     ex13     ex17~    ex3      exam12   exam13~

[ysk@192 ~]$ cat ex

按下tab+tab 或者esc+ '?'

4.  编辑并运行书上P91页4.5.2节引号的相关脚本和命令;

[ysk@192 ~]$ cat ex

echo "current directory is `pwd`"

echo "home directory is $HOME"

echo "file*.?"

echo "directory ‘$HOME’ "

echo  directory ‘$HOME’

[ysk@192 ~]$ ./ex

current directory is /home/ysk

home directory is /home/ysk

file*.?

directory ‘/home/ysk’

directory ‘/home/ysk’

[ysk@192 ~]$

5.  编辑并运行书上P108页例4.9,体会位置参数的相关用法;

echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

shift

echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

shift 4

echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9

[ysk@localhost ~]$ ./ysk_1 A B C D E F G H I J K

./ysk_1 A B C D E F G H I

./ysk_1 B C D E F G H I J

./ysk_1 F G H I J K

6.  编辑并运行书上P125页,例4.13,体会shell脚本中条件表达式、算数表达式、逻辑运算的使用方法,同时需要注意实验室linux环境与书本中linux版本的不一致;

ysk_2:

f [ 3 -gt 2 ]

then

echo "3>2"

else

echo "3<=2"

fi

[ysk@localhost ~]$ ./ysk_2

3>2

if [[ 3 -gt 2 ]]

then

echo "3>2"

else

echo "3<=2"

fi

[ysk@localhost ~]$ ./ysk_2

3>2

[[后面要留出一个空格

]]前面也要留出一个空格

f [ 3 -lt 2 -o 3 -gt 2 ]

then

echo "true"

else

echo "false"

fi

[ysk@localhost ~]$ ./ysk_2

true

不能把里面的-o 写成||

否则结果是false

7.  编辑并运行书上P130页,例4.15,体会值表方式的for循环与位置参数相结合的使用方法;

dir=$1;shift

if [ -d $dir ]

then

cd $dir

for name

do

if [ -f $name ]

then cat $name

echo "End of ${dir}/$name"

else

echo "Invalid file name: ${dir}/$name"

fi

done

else echo "Bad directory name:$dir"

fi

[ysk@192 ~]$ ./ex144 code 111 222

#echo "sa"

echo "sa"

End of code/111

if test -f "$1"

then echo "$1 is a file"

else echo "$1 is not a file"

fi

End of code/222

[ysk@192 ~]$

if和[之间需要有空格

[ test -d $dir ] 好像不行 [ -d $dir ]可以

8.  编辑并运行书上P131页,例4.16,体会算数表达式方式的for循环用法;

for((i=1;i<=$1;i++))

do

for((j=1;j<=i;j++))

do

echo -n "*"

done

echo ""

done

echo "end!"

[ysk@192 ~]$ ./ex145 4

*

**

***

****

end!

[ysk@192 ~]$

9.  编辑并运行书上P134页,例4.19,体会shell脚本中函数的使用;

func()

{

echo "Let's begin now."

echo $a $b $c

echo $1 $2 $3

echo "The end."

}

a="Working directory"

b="is"

c=`pwd`

func Welcome You Byby

echo "Today is `date`"

[ysk@192 ~]$ chmod a+x ex146

[ysk@192 ~]$ ./ex146

Let's begin now.

Working directory is /home/ysk

Welcome You Byby

The end.

Today is Sun Apr 16 04:17:01 PDT 2017

[ysk@192 ~]$

10.自己编写shell脚本,实现以下功能:

11.Shell脚本文件名为sq,执行时接受2-10范围内的一个整数作为输入参数,在屏幕上用+号、@号和 &号画出以给定参数为边长的正方形。

&特殊字符 echo时需要加引号" "或' '

12.例如:输入命令$ sq 4并回车,则屏幕上会绘制如下的正方形,(注:其中第2、3行上的&符号之间有两个空格)

@++@

&   &

&   &

@++@

read x

if [ $x -lt 2 -o $x -gt 10 ]

then

echo "x must in [2,10]"

exit

fi

echo -n @

for((i=1;i<=$x-2;i++))

do

echo -n +

done

echo @

for((i=1;i<=$x-2; i++))

do

echo -n '&'

for((j=1;j<=$x-2;j++))

do

echo -n " "

done

echo "&"

done

echo -n @

for((i=1;i<=$x-2;i++))

do

echo -n +

done

echo @

[ysk@192 ~]$ ./t2_10

4

@++@

&  &

&  &

@++@

[ysk@192 ~]$ ./t2_10

12

x must in [2,10]

[ysk@192 ~]$ ./t2_10

6

@++++@

&    &

&    &

&    &

&    &

@++++@

[ysk@192 ~]$

实验报告要求:在实验步骤中写出主要的脚本代码,并且最后要写实验小结

实验三 实验名称: Linux环境下程序的编译和调试(2学时)

一、实验目的

1、 掌握gcc编译器在预处理、编译、汇编和连接各个阶段的用法

2、 掌握gdb调试工具的常用命令

二、实验内容

1.   使用gcc编译器中的预处理选项

2.   使用gcc编译器中的编译程序选项

3.   使用gdb调试工具的使用

三、实验步骤

1.   编写并验证书本P180页例题6.1

hello.c

#include

#define fatal "!!!!!!"

main()

{

printf("display -D variable %s\n",DOPTION);

printf("display overwrite fatal=%s\n",fatal);

printf("Hello ,everybody!!\n");

}

testI.h

#define fatal "please call Lawrence for help"

[ysk@localhost ~]$ gcc -I ./tmp -D DOPTION='"testing -D" ' -D fatal -E hello.c

# 1 "hello.c"

# 1 ""

# 1 ""

# 1 "hello.c"

# 1 "./tmp/testI.h" 1

In file included from hello.c:1:

./tmp/testI.h:1:1: warning: "fatal" redefined

: warning: this is the location of the previous definition

# 2 "hello.c" 2

hello.c:2:1: warning: "fatal" redefined

./tmp/testI.h:1:1: warning: this is the location of the previous definition

main()

{

printf("display -D variable %s\n","testing -D");

printf("display overwrite fatal=%s\n","!!!!!!");

printf("Hello ,everybody!!\n");

}

[ysk@localhost ~]$

出现了重复的宏定义,如果都没有相关的定义那么 -D fatal 后 fatal的值为1

//#include

#define fatal "please call Lawrence for help"

main()

{

printf("display -D variable %s\n","testing -D");

printf("display overwrite fatal=%s\n","please call Lawrence for help");

printf("Hello ,everybody!!\n");

}

控制台:

[ysk@localhost ~]$ gcc -D DOPTION=' "testing -D"' hello.c

hello.c: In function ‘main’:

hello.c:7: warning: incompatible implicit declaration of built-in function ‘printf’

[ysk@localhost ~]$ ./a.out

display -D variable testing -D

display overwrite fatal=please call Lawrence for help

Hello ,everybody!!

[ysk@localhost ~]$ gcc -D DOPTION=' "testing -D"' hello.c

hello.c: In function ‘main’:

hello.c:7: warning: incompatible implicit declaration of built-in function ‘printf’

[ysk@localhost ~]$ ./a.out

display -D variable testing -D

display overwrite fatal=please call Lawrence for help

Hello ,everybody!!

2.   编写并验证书本P181页例题6.2

#include

int main()

{

int r;

printf("Enter an integer,please!\n");

scanf("%d",&r);

square(r);

return 0;

}

#include

int square(int x)

{

printf("The square=%d\n",x*x);

return 0;

}

此时直接gcc  meng1.c或者gcc meng2.c貌似是不可以的

正确的做法:

[ysk@localhost ~]$ gcc -c meng2.c

[ysk@localhost ~]$ gcc meng1.o meng2.o -o meng12

[ysk@localhost ~]$ ./meng12

Enter an integer,please!

2

The square=4

3.   编写并验证书本P193页6.2.6应用示例

第四章的一些知识点:

1.关于将路径添加到环境变量PATH

[ysk@192 ~]$ ./aaa

hello,world

hello,world2

[ysk@192 ~]$ PATH=$PATH:./

[ysk@192 ~]$ aaa

hello,world

hello,world2

也就是说在当前(任意)文件夹,不用再./xxx执行文件,而是可以直接用文件名执行。

2.将变量送入进程转出区

sd

exam12:

major=“English”

echo “His major is $major”

exam13:

echo “her major is $major”

[ysk@192 ~]$ exam12

bash: ./exam12: Permission denied

[ysk@192 ~]$ chmod a+x exam12

[ysk@192 ~]$ chmod a+x exam13

[ysk@192 ~]$ exam13

“her major is ”

[ysk@192 ~]$ exam12

“His major is “English””

[ysk@192 ~]$ major="computer science"

[ysk@192 ~]$ export major

[ysk@192 ~]$ exam12

“His major is “English””

[ysk@192 ~]$ exam13

“her major is computer science”

3.只有使用$((算术表达式))的形式才能返回表达式的值

[ysk@192 code]$ echo "(12*9)"

(12*9)

[ysk@192 code]$ echo (12*9)

bash: syntax error near unexpected token `12*9'

[ysk@192 code]$ echo "((12*9))"

((12*9))

[ysk@192 code]$ echo ((12*9))

bash: syntax error near unexpected token `('

[ysk@192 code]$ echo "$((12*9))"

108

[ysk@192 code]$ echo $(12*9)

bash: 12*9: command not found

[ysk@192 code]$ echo $((12*9))

108

[ysk@192 code]$ let "i=2*3"

[ysk@192 code]$ i

bash: i: command not found

[ysk@192 code]$ $i

bash: 6: command not found

[ysk@192 code]$ echo $i

6

[ysk@192 code]$ echo "$i"

6

[ysk@192 code]$ let "i=2*3"

[ysk@192 code]$ i

bash: i: command not found

[ysk@192 code]$ $i

bash: 6: command not found

[ysk@192 code]$ echo $i

6

[ysk@192 code]$ echo "$i"

6

[ysk@192 code]$ ((j=i*2))

[ysk@192 code]$ echo $j

12

[ysk@192 code]$ echo "$j"

12

4.test -f 文件名

222:

if test -f "$1"

then echo "$1 is a file"

else echo "$1 is not a file"

fi

[ysk@192 code]$

333

23

x

23

[ysk@192 code]$ chmod a+x 222

[ysk@192 code]$ 222

is not a file

[ysk@192 code]$ 222 222

222 is a file

[ysk@192 code]$ 222 111

111 is a file

[ysk@192 code]$ ^C

[ysk@192 code]$ 222 aaa

aaa is not a file

ex14:

read k

echo $k

((k=k-1))

let "i=k+1"

echo $k

echo $i

[ysk@192 ~]$ ./ex14

4

4

3

4

5.read /echo

333:

read x

echo x

echo $x

[ysk@192 code]$

333

23

x

23

6.case的用法

444:

read x

case $x in

1) echo x=1;;

2) echo x=2;;

esac

case $x 后面要加in,然后不用打:之类的

然后是一系列的),)前面是匹配的值,后面是操作,记得要打;;

将case倒过来写esac来结束

[ysk@192 code]$ 444

1

x=1

[ysk@192 code]$ 444

2

x=2

[ysk@192 code]$ 444

3

555:

[ysk@192 code]$ chmod a+x 555

[ysk@192 code]$ 555

1

x=1

[ysk@192 code]$ 555

2

x=2

[ysk@192 code]$ 555

3

read x

case $x in

1)

echo x=1

;;

2)

echo x=2

;;

esac

7.

ex11

echo –n "Type in a number (1-10)"

read num

if [ "$num" -lt 1 -o "$num" -gt 10 ]

then echo "Error input"

exit 2

elif [ ! "$num" -lt 5 ]

then echo "it is not less 5"

else echo "it is less 5"

fi

echo "accept number in value"

[ysk@192 ~]$ ./ex11

–n Type in a number (1-10)

5

it is not less 5

accept number in value

[ysk@192 ~]$ ./ex11

–n Type in a number (1-10)

12

Error input

不知为何双中括号 [[ ]]一直不行

[[ ]]中要用||和&&来表示-o -a

for((i=1;i<=5;i++))

do

echo $i

done

[ysk@192 ~]$ ./ex12

1

2

3

4

5

8. while

ex13:

read k

while [ "$k" -gt 0 ]

do

echo $k

((k=k-1))

done

[ysk@192 ~]$ ./ex13

4

4

3

2

1

9.函数

还没研究清楚:

function valtest()

{

echo "Begin to test how to pass values"

echo $a $b $c

echo $1 $2 $3 $4

echo "The end of function valtest"

return 1

}

a="current working directory"

b="is"

c=`pwd`

valtest Let's begin to use Linux

## k=$(( valtest Let's begin to use Linux ))

echo "Today is `date`"

## echo $k

实验四 实验名称:Linux进程控制程序的设计和实现(2学时)

一、实验目的

1、 理解系统调用和库函数的使用方法和格式

2、 掌握文件操作相关的系统调用函数的使用和编程

3、 掌握进程控制相关的系统调用函数的原理、语法和编程应用

二、实验内容

1.   使用文件操作系统调用函数open,read,write进行程序设计

2.   创建子进程的系统调用fork()设计程序,观察程序的执行结果

3.   比较子进程等待函数wait和waitpid的异同

三、实验步骤

1.编辑并运行下列代码,理解fork函数的执行原理

int main()

{ int i;

int pid;

pid=fork();

if (pid<0) printf(“error”)

else if (pid == 0)

{   for (i = 1; i < 3; i++)

printf("This is child process\n");

}

else

{   for (i = 1; i < 3; i++)

printf("This is parent process\n");

}

}

#include

int main()

{

int i;

int pid;

pid=fork();

if (pid<0) printf("error");

else if (pid == 0)

{

for (i = 1; i < 3; i++)

printf("This is child process\n");

}

else

{

for (i = 1; i < 3; i++)

printf("This is parent process\n");

}

return 0;

}

[ysk@localhost ~]$ vi c1.c

[ysk@localhost ~]$ gcc c1.c-o ec1

gcc: c1.c-o: No such file or directory

[ysk@localhost ~]$ gcc c1.c -o ec1

[ysk@localhost ~]$ ec1

This is parent process

This is parent process

[ysk@localhost ~]$ This is child process

This is child process

vi c1.c

[ysk@localhost ~]$ ec1

This is parent process

This is parent process

[ysk@localhost ~]$ This is child process

This is child process

2.编辑并执行下列程序,观察并分析程序执行结果

int com=0;

main()

{

pid_t pid;

pid=fork();

if(pid<0)

then printf("error");

else if(pid==0)

then

{com=1};

else

{com=com+1};

printf{"com=%d\n",com};

}

#include

#include

#include

int com=0;

int main()

{

pid_t pid;

pid=fork();

if(pid<0) printf("error");

else if(pid==0) com=1;

else com=com+1;

printf("com=%d\n",com);

return 0;

}

[ysk@localhost ~]$ vi c2.c

[ysk@localhost ~]$ gcc c2.c -o ec2

[ysk@localhost ~]$ ec2

com=1

[ysk@localhost ~]$ com=1

ec2

com=1

[ysk@localhost ~]$ com=1

3.编辑并执行下列程序,观察并分析进程ID获取函数的用法

#include

#include

main()

{

pid_t pid;

pid=fork();

if(pid<0) printf("fork error!\t");

else if(pid==0)

printf("child process now! pid=%d ppid=%d\t",getpid(),getppid());

elseprintf("parent process now! pid=%d child_pid=%d\t",getpid(),pid);

}

#include

#include

#include

int main()

{

pid_t pid;

pid=fork();

if(pid<0) printf("fork error!\n");

else if(pid==0)

printf("child process now! pid=%d ppid=%d\n",getpid(),getppid());

else

printf("parent process now! pid=%d child_pid=%d\n",getpid(),pid);

return 0;

}

[ysk@192 ~]$ ./ec3

parent process now! pid=2692 child_pid=2693

[ysk@192 ~]$ child process now! pid=2693 ppid=1

因为用fork函数创建子进程,父进程没有等待子进程的退出,这可能导致子进程编程孤儿进程,被init进程接管,所以父进程id为1

4. 编写程序验证书本P213页的例题7.3

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

pid_t pid,old_ppid,new_ppid;

pid_t child,parent;

parent=getpid();

if((child=fork())<0)

{

fprintf(stderr,"%s:fork of child failed:%s\n",argv[0],strerror(errno));

exit(1);

}

else if(child==0)

{

old_ppid=getppid();

sleep(2);

new_ppid=getppid();

}

else

{

sleep(1);

exit(0);

}

printf("Original parent:%d\n",parent);

printf("Child:%d\n",getpid());

printf("Child's old ppid:%d\n",old_ppid);

printf("Child's new ppid:%d\n",new_ppid);

exit(0);

}

gcc c4.c -o ec4

[ysk@192 ~]$ ./ec4

[ysk@192 ~]$ Original parent:2759

Child:2760

Child's old ppid:2759

Child's new ppid:1

./ec4

[ysk@192 ~]$ Original parent:2761

Child:2762

Child's old ppid:2761

Child's new ppid:1

5.编写程序验证PPT中的相关例题,思考运行结果。

实验五 实验名称:Linux进程通信的程序设计和实现(2学时)

一、实验目的

1、 掌握进程通信相关的系统调用的语法格式

2、 掌握pipe,kill和消息队列函数在父子进程通信时的具体用法

3、 能够读、写系统调用程序,理解程序的输出结果。

二、实验内容

1.   在程序设计中使用pipe函数进行基于管道的进程通信

2.   在程序设计中使用kill函数进行基于信号量的进行通信

3.   在程序设计中使用消息队列机制实现进行通信

三、实验步骤

1.参考下列伪码,编辑并执行pipe函数的程序

#include

#include

#include

int main(intargc,char **argv)

{

static const char mesg[]="Happy NewYear";

char buf[BUFSIZ];

size_t rcount,wcount;

int p_fd[2];

size_t n;

if(pipe(p_fd)<0){

printf(“pipe error”);

exit(EXIT_FAILURE);

}

printf("Read end=fd %d,write end=fd%d\n",p_fd[0],p_fd[1]);

n=strlen(mesg);

if((wcount=write(p_fd[1],mesg,n))!=n){

printf(“write error”);

exit(EXIT_FAILURE);

}

if((rcount=read(p_fd[0],buf,BUFSIZ))!=wcount){

printf(“read error”);

exit(EXIT_FAILURE);

}

printf("Read from pipe\n",buf);

close(p_fd[0]);

close(p_fd[1]);

return 0;

}

#include

#include

#include

#include

#include

int main(int argc,char **argv)

{

static const char mesg[]="Happy NewYear";

char buf[BUFSIZ];

size_t rcount,wcount;

int p_fd[2];

size_t n;

if(pipe(p_fd)<0){

printf("pipe error");

exit(EXIT_FAILURE);

}

printf("Read end=fd %d,write end=fd %d\n",p_fd[0],p_fd[1]);

n=strlen(mesg);

if((wcount=write(p_fd[1],mesg,n))!=n){

printf("write error");

exit(EXIT_FAILURE);

}

if((rcount=read(p_fd[0],buf,BUFSIZ))!=wcount){

printf("read error");

exit(EXIT_FAILURE);

}

printf("Read from pipe\n",buf);

close(p_fd[0]);

close(p_fd[1]);

return 0;

}

[ysk@localhost ~]$ ./sy5_1e

Read end=fd 3,write end=fd 4

Read from pipe

[ysk@localhost ~]$

2.在下列伪码中加入头文件,编辑运行,理解kill函数

int main()

{ pid_tchild;

int status, retval;

if((child=fork())<0) {perror(“fork”);  exit(EXIT_FAILURE); }

else if (child==0) {

printf(“Child’s ID:%d\n”, child);

sleep(20);

exit(0); }

else {

if((waitpid(child,&status,WNOHANG))==0){

retval=kill(child,SIGKILL);

if (retval){

perror(“kill”);

waitpid(child,&status,0);

}

else printf(“%d iskilled”,child);

}

}

#include

#include

#include

#include

#include

#include

int main()

{

pid_t child;

int status, retval;

if((child=fork())<0)

{

perror("fork"); exit(EXIT_FAILURE);

}

else if (child==0)

{

printf("Child's ID:%d\n", child);

sleep(20);

exit(0);

}

else

{

if( (waitpid(child,&status,WNOHANG) )==0)

{

retval=kill(child,SIGKILL);

if (retval)

{

perror("kill");

waitpid(child,&status,0);

}

else printf("%d is killed\n",child);

}

}

return 0;

}

[ysk@localhost ~]$ ./sy5_2e

2448 is killed

[ysk@localhost ~]$

3.编辑并运行书本P218页进程使用消息队列进行通信的例题。思考消息队列的使用机制和运作机制。

#include

#include

#include

#include

#include//5

#include

#include

#define BUFSZ 512

struct msg

{//10

long type;

char text[BUFSZ];

};

int main(void)//15

{

int qid;

key_t key;

int len1,len2;

struct msg pmsg_w,pmsg_r;//20

key=IPC_PRIVATE;

if( (qid=msgget(key,IPC_CREAT|0666 ) )<0 )

{

perror("msgget:create");//25

exit(EXIT_FAILURE);

}

puts("Enter message to past");

if(fgets(pmsg_w.text,BUFSZ,stdin)==NULL)

{//30

puts("Wrong,no message to post.");

exit(EXIT_FAILURE);

}

pmsg_w.type=10;

len1=strlen(pmsg_w.text);//35

if(msgsnd(qid,&pmsg_w,len1,IPC_NOWAIT )<0)

{

perror("msgsnd");

exit(EXIT_FAILURE);

}//40

puts("message posted.");

puts("***************");

len2=msgrcv(qid,&pmsg_r,BUFSZ,10,IPC_NOWAIT|MSG_NOERROR);

if(len2>0)//45

{

pmsg_r.text[len2]='\0';

printf("reading queue id=%05d\n",qid);

printf("message type=%05ld\n",pmsg_r.type);

printf("message length=%d bytes\n",len2);//50

printf("message text=%s\n",pmsg_r.text);

}

else

{

perror("msgrcv");

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);

}

[ysk@localhost ~]$ ./sy5_3e

Enter message to past

Happy New Year!

message posted.

***************

reading queue id=131076

message type=00010

message length=16 bytes

message text=Happy New Year!

[ysk@localhost ~]$

4.编辑并运行书本P220页例题7.7, 思考和验证运行结果。

#include

#include

#include

#include

#include//5

#include

int main()

{

pid_t pid;//10

int num;

if( (pid=fork())<0 )

{

perror("fork");

exit(EXIT_FAILURE);//15

}

else if(pid==0)

{

sleep(30);

}//20

else

{

printf("Sending SIGCHLD to %d\n",pid);

num=kill(pid,SIGCHLD);

if(num<0)//25

perror("kill:SIGCHLD");

else

printf("%d still alive\n",pid);

printf("Killing %d\n",pid);

if( (kill(pid,SIGTERM) )<0 )

perror("kill:SIGTERM");

waitpid(pid,NULL,0);

}

exit(EXIT_SUCCESS);

}

[ysk@localhost ~]$ ./sy5_4e

Sending SIGCHLD to 3100

3100 still alive

Killing 3100

[ysk@localhost ~]$

5.编写程序验证PPT中的相关例题,思考运行结果。

[ysk@192 code]$  333 23 x 23

在linux下恶臭hellotext中作用的?,《Linux内核与程序设计》实验学习笔记相关推荐

  1. linux下dev目录的作用,Android/Linux根目录下常见目录作用

    当adb shell进入Android系统内部后,ls会看到根目录下出现不少目录,如dev.sys.mnt等目录,对于这些目录的作用常常让人模棱两可,有必要对其学习了解. 首先要明白目录也是一种文件, ...

  2. Linux 下各个目录的作用及内容

    Linux 下各个目录的作用及内容 在 Linux 下,我们看到的是文件夹(目录): 在早期的 UNIX 系统中,各个厂家各自定义了自己的 UNIX 系统文件目录,比较混乱.Linux 面世不久后,对 ...

  3. 【OS】Linux下/dev/shm的作用及ORA-00845错误的处理

    [OS]Linux下/dev/shm的作用 对/dev/shm认识 发表于 2011 年 09 月 25 日 由 惜分飞 一./dev/shm理论 /dev/shm/是linux下一个非常有用的目录, ...

  4. Linux下的文件目录及其作用

    Linux下的文件目录及其作用 Linux分区与Windows分区的不同 在Windows系统中, 一切东西都是存放在硬盘上的.启动系统后,先确定硬盘,再确定硬盘上的分区以及每个分区所对应文件系统,最 ...

  5. Linux脚本保存管道中的变量,Linux下管道重定向使用以及Shell编程(操作系统)

    实验名称:Linux的基本操作 实验目的: 1.了解管道和重定向 2.熟悉基本的Linux脚本的编写 实验环境:Ubuntu 12.4(32位,简体中文) 实验内容: 1.将当前用户目录下的文件清单输 ...

  6. php文件内含有隐藏的^m字符,【整理】如何取消Linux下,vi中显示的^M符号

    [整理]如何取消Linux下,vi中显示的^M符号 [背景知识] ^M 是ascii中的'\r', 回车符,是16进制的0x0D,8进制的015,十进制的13. 对于换行这个动作,unix下一般只有一 ...

  7. Linux下高性能网络编程中的几个TCP/IP选项

    Linux下高性能网络编程中的几个TCP/IP选项 转自:http://blog.chinaunix.net/u/12592/showart.php?id=2064847 最近在新的平台上测试程序,以 ...

  8. Linux下gcc编译中关于头文件与库文件搜索路径相关问题

    如何指定GCC的默认头文件路径 网上偶搜得之,以之为宝:) 原地址:http://blog.chinaunix.net/u/28781/showart.php?id=401631 ========== ...

  9. Linux下CMake工程中gtestgmock的安装与使用

    Linux下CMake工程中gtest&gmock的安装与使用 gtest和gmock是什么和功能以及用法可参考以下两篇文章,都相当给力! gtest <玩转Google开源C++单元测 ...

最新文章

  1. python显示当前时间
  2. 求最大值_Excel求最大值地球人都知道,那要求出第2、第3、第N大值呢?
  3. 基于机器学习的捡球机器人设计与实现(探索)第1篇——树莓派系统的安装与配置(20190106)
  4. python延时队列_如何通过Python实现RabbitMQ延迟队列
  5. git ssh拉取代码_win10下git初始安装及配置工作
  6. vue-cli安装和使用
  7. Cmake安装遇到问题
  8. if condition 大于_EXCEL中IF函数由浅入深实例分析
  9. QT_UDP传输小结
  10. lightclients将于4月27日主持召开EIP-3074社区会议
  11. php日程 增删改查,使用Fullcalendar管理日程事件(增删改查拖放)
  12. 1,使用three20来创建tableview
  13. 软件安装 | 神器VAX Patch VA_X.DLL 安装位置的问题 for VS2008 , VS2010 , VS2011
  14. 嵌入式驱动开发遇到version magic不匹配解决办法
  15. 千帆竞发势如虹 明光政策送东风 首届明光大赛来了
  16. 分享一些可用的淘宝(1688)关于订单信息获取的相关接口(开放API收费)
  17. 《滕王阁序》古文鉴赏
  18. IIC OLED笔记
  19. php echarts 嵌套饼图,echarts绘制嵌套环形图/ 双饼图
  20. Serverless开源框架对比

热门文章

  1. 一个web前端专科生面试后的感概
  2. 农业统计分析系列2-试验设计
  3. Markdown中如何打对勾/对号
  4. 华为服务器故障灯不开机_华为手机开不了机指示灯亮怎么办?
  5. android 电视怎么投屏,安卓手机怎么投屏到电视
  6. 结束 oracle 锁 ps -ef|grepp.spid,oracle 解锁表剔除去session 和kill
  7. I2P和TOR 有趣网络精灵
  8. Java常见问题之Data too long for column 'orResponse' at row 1
  9. android 熄屏 socket断开,Android 休眠导致的问题Socket断开
  10. 1字符集 iso latin_ISO Latin-1字符集