版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2016年秋季学期A卷、考查、开卷
课程名称嵌入式系统开发
命题教师:姜愉适用班级:物联本151、152、153班
答卷说明:1.本试卷共1页,1个大题,满分100分,时间120分钟。
学号:1504412241姓名:蓝意乐班别:物联本152
题号一总分评分人
得分
一、作品题:(本大题共1大题,共100分)
实践总结要求包括:
1、3000字以上;(10分)
2,详细论述Linux系统下各目录的主要功能;(10分)
3、论述shell的基本工作原理;(10分)
4、结合程序实例详细论述常用的5种进程通信方式;(20分)
5,对进程与线程的区别进行分析;(10分)
6、结合实例对gcc、gdb、make的实现方法做详尽论述;(20分)
7,结合套接字理论对TCP、UDP通信原理进行论述;(10分)
8、学习心得体会。(10分)
第1页共1页
一、详细论述Linux系统下各目录的主要功能。
目录
1、树状目录结构图
2、/目录
3、/etc/目录
4、/usi7目录
5、/var/目录
6、/proc/目录
7、/dev/目录
卜面红色字体为比较窜要的目录
1、树状目录结构图
第2页共2页
t/Jggji
_[bn」的T4箕用的I阱
-―—)8动文件.所有与系茨8
83』就有关的文件知某存在过里
-------(一dev,设备文件
(一——系毓不和大部分应用
----------"J程序的g局配■文件
----------1hone,使用者个人冢目录
----------(ib/[系挽联摩文怦
-------(E/常雕蛇点
----------(0"/第三方&序安然
----------(proc/显:T东现状55文件
----------(,81」昔般家目呆
----------(sbtn1餐利一专用杆,
----------[imp/*「文件
2、/目录
目录描述
/第一层次结构的根、整个文件系统层次结构的根目录。
需要在单用户模式可用的必要命令(可执行文件);面向所有用户,例如:ca
/bin/
t、Is、cp,和/usr/bin类似。
第3页共3页
/boot/引导程序文件,例如:kernekinitrd;时常是一个单独的分区⑹
/dev/必要设备,例如:,/dev/null.
特定主机,系统范围内的配置文件。
关于这个名称目前有争议。在贝尔实验室关于UNIX实现文档的早期版本中,/
etc被称为/etcetra目录,[7]这是由于过去此目录中存放所有不属于别处的所
/etc/
有东西(然而,FHS限制/etc存放静态配置文件,不能包含二进制文件)。[8]
自从早期文档出版以来,目录名称已被以各种方式重新称呼。最近的解释包括
反向缩略语如:"可编辑的文本配置"(英文"EditableTextConfiguration")或
11扩展工具箱"(英文"ExtendedToolChest")«[9]
/etc/opt//opt/的配置文件
/etc/Xll/X_Window系统(版本11)的配置文件
/etc/sgml/SGML的配置文件
/etc/xml/XML的配置文件
/home/用户的家目录,包含保存的文件、个人设置等,一般为单独的分区。
/lib//bin/and/sbin/中二进制文件必要的库文件。
/media/可移除媒体(如CD-ROM)的挂载点(在FHS-2.3中事现)。
在ext3文件系统中,当系统意外崩溃或机器意外关机,会产生一些文件碎片
在这里。当系统在开机启动的过程中fsck工具会检查这里,并修复已经损坏的
/lost+found
文件系统。当系统发生问题。可能会有文件被移动到这个目录中,可能需要用
手工的方式来修复,或移到文件到原来的位置上。
临时挂载的文件系统。比如cdrom,u盘等,直接插入光驱无法使用,要先挂载
/mnt/
后使用
/opt/可选应用软件包。
虚拟文件系统,将内核叮进程状态归档为文本文件(系统信息都存放这目录
/proc/下)。例如:uptime>networko在Linux中,对应Proofs格式挂载。该目录
下文件只能看不能改(包括root)
/root/超级用户的家目录
必要的系统二进制文件,例如:init、ip、mountosbin目录下的命令,普通
/sbin/
用户都执行不了。
/srv/站点的具体数据,由系统提供。
/tmp/临时文件(参见/var/tmp),在系统重启时目录中文件不会被保留。
/usr/默认软件都会存于该目录下。用于存储只读用户数据的第二层次;包含绝大多
第4页共4页
数的(多)用户工具和应用程序。
变量文件一一在正常运行的系统中其内容不断变化的文件,如日志,脱机文件
/var/和临时电子邮件文件。有时是一个单独的分区。如果不单独分区,有可能会把
整个分区充满。如果单独分区,给大给小都不合适。
3、/etc/目录
特定主机系统范围内的配置文件。
目录描述
/etc/rc/etc/rc.d
启动、或改变运行级时运行的scripts或scripts的目录.
/etc/rc*.d
/etc/hosts本地域名解析文件
/etc/sysconfig/networkIP、掩码、网关、主机名配置
/etc/resolv.confDNS服务器配置
/etc/fstab开机自动挂载系统,所有分区开机都会自动挂载
设定系统启动时Init进程将把系统设置成什么样的runlevel
/etc/inittab
及加载相关的启动文件配置
/etc/exports设置NFS系统用的配置文件路径
/etc/init.d这个目录来存放系统启动脚本
/etc/profile,
全局系统环境配置变量
/etc/csh.login,/etc/csh.cshrc
/etc/issue认证前的输出信息,默认输出版本内核信息
/etc/motd设置认证后的输出信息,
当前安装的文件系统列表.由scripts初始化,并由mount命
/etc/mtab令自动更新.需要一个当前安装的文件系统的列表时使用,
例如df命令
/etc/group类似/etc/passwd,但说明的不是用户而是组.
用户数据库,其中的域给出了用户名、真实姓名、家目录、
/etc/passwd
加密的口令和用户的其他信息.
在安装了影子口令软件的系统上的影子口令文件.影子口令
/etc/shadow文件将/etc/passwd文件中的加密口令移动到/etc/shadow
中,而后者只对root可读.这使破译口令更困难.
/etc/sudoers可以sudo命令的配置文件
/etc/syslog.conf系统日志参数配置
第5页共5页
/etc/login.defs设置用户帐号限制的文件
确认安全终端,即哪个终端允许root登录.一般只列出虚拟
/etc/securetty控制台,这样就不可能(至少很困难)通过modem或网络闯
入系统并得到超级用户特权.
/etc/printcap类似/etc/termcap,但针对打印机.语法不同.
列出可信任的shell.chsh命令允许用户在本文件指定范围
内改变登录shell.提供一台机器FTP服务的服务进程ftpd检
/etc/shells
查用户shell是否列在/etc/shells文件中,如果不是将不允
许该用户登录.
如果服务器是通过xinetd模式运行的,它的脚本要放在这
/etc/xinetd.d个目录下。有些系统没有这个目录,比如Slackware,有些
老的版本也没有。在RedhatFedora中比较新的版本中存在。
/etc/opt//opt/的配置文件
/etc/Xll/X_Window系统(版本11)的配置文件
/etc/sgml/SGML的配置文件
/etc/xml/XML的配置文件
/etc/skel/默认创建用户时,把该目录拷贝到家目录下
4、/usr/目录
默认软件都会存于该目录卜;用于存储只读用户数据的第二层次;包含绝大多数的用户工具和应用程序.
目录描述
/usr/XHR6存放X-Windows的目录;
/usr/games存放着XteamLinux自带的小游戏;
/usr/docLinux技术文档;
/usr/include用来存放Linux下开发和编译应用程序所需要的头文件;
/usr/lib存放一些常用的动态链接共享库和静态档案库;
/usr/man帮助文档所在的目录;
/usr/srcLinux开放的源代码,就存在这个目录,爱好者们别放过哦;
/usr/bin/非必要可执行文件(在单用户模式中不需要);面向所有用户。
/usr/lib//usr/bin/和/usr/sbin/中二进制文件的库。
/usr/sbin/非必要的系统二进制文件,例如:大量网络服务的守护进程。
第6页共6页
/usr/share/体系结构无关(共享)数据。
/usr/src/源代码,例如呐核源代码及其头文件。
/usr/XHR6/XWindow系统版本11,Release6.
本地数据的第三层次,具体到本台主机。通常而言有进一步的子目录,例如:
/usr/local/bin/、lib/、share/.这是提供给一般用户的/usr目录,在这里安装一般的应用
软件;
5、/var/目录
/var包括系统般运行时要改变的数据.每个系统是特定的,即不通过网络与其他计算机共享.
目录描述
/var/log/message日志信息,按周自动轮询
/var/spool/cron/root定时器配置文件目录,默认按用户命名
记录登陆系统存取信息的文件,不管认证成功还是认证失败都
/var/log/secure
会记录
/var/log/wtmp记录登陆者信息的文件,last,who,w命令信息来源于此
当邮件服务未开启时,所有应发给系统管理员的邮件都将堆放
/var/spool/clientmqueue/
在此
/var/spool/mail/邮件目录
比/tmp允许的大或需要存在较长时间的临时文件.(虽然系统
/var/tmp
管理员可能不允许/var/tmp有很旧的文件.)
/var/lib系统正常运行时要改变的文件.
/usr/local中安装的程序的可变数据(即系统管理员安装的程
/var/local序).注意,如果必要,即使本地安装的程序也会使用其他/var目
录,例如/var/lock.
锁定文件.许多程序遵循在/var/lock中产生一个锁定文件的约
/var/lock定,以支持他们正在使用某个特定的设备或文件.其他程序注意
到这个锁定文件,将不试图使用这个设备或文件.
/var/log/各种程序的Log文件,特别是login(/var/log/wtmplog所有到
第7页共7页
系统的登录和注销)和syslog(/var/log/messages里存储所有核
心和系统程序信息./var/bg里的文件经常不确定地增长,应该
定期清除.
保存到下次引导前有效的关于系统的信息文件.例如,
/var/run
/var/run/utmp包含当前登录的用户的信息.
应用程序缓存数据。这些数据是在本地生成的一个耗时的I/O
/var/cache/或计算结果。应用程序必须能够再生或恢复数据。缓存的文件
可以被删除而不导致数据丢失。
6、/proc/目录
虚拟文件系统,将内核与进程状态归档为文本文件(系统信息都存:放这目录下)。
例如:uptime、networko在Linux「3对应Procfs格式挂载。该目录下文件只能看不能改(包括root)
目录描述
/proc/meminfo查看内存信息
还记得top以及uptime吧?没错!上头的三个平均数值就是记录在
/proc/loadavg
此!
/proc/uptime就是用uptime的时候,会出现的资讯啦!
/proc/cpuinfo关于处理器的信息,如类型、厂家、型号和性能等。
加载kernel时所下达的相关参数!查阅此文件,可了解系统是如何
/proc/cmdline
启动的!
/proc/filesystems目前系统已经加载的文件系统罗!
/proc/interrupts目前系统上面的IRQ分配状态。
/proc/ioports目前系统上面各个装置所配置的I/O位址。
/proc/kcore这个就是内存的大小啦!好大对吧!但是不要读他啦!
/proc/modules目前我们的Linux已经加载的模块列表,也可以想成是驱动程序啦!
/proc/mounts系统已经挂载的数据,就是用mount这个命令呼叫出来的数据啦!
到底系统挂加载的内存在哪里?呵呵!使用掉的partition就记录在此
/proc/swaps
啦!
使用fdisk-1会出现目前所有的partition吧?在这个文件当中也有
/proc/partitions
纪录喔!
第8页共8页
/proc/pci在PCI汇流排上面,每个装置的详细情况!可用Ispci来查阅!
/proc/version核心的版本,就是用uname-a显示的内容啦!
/proc/bus/*一些汇流排的装置,还有U盘的装置也记录在此喔!
7、/dev/目录
设备文件分为两种:块设备文件(b)和字符设备文件⑹
设备文件般存放在/dev目录下,
对常见设备文件作如下说明:
目录描述
/dev/hd[a-t]IDE设备
/dev/sd[a-z]SCSI设备
/dev/fd[0-7]标准软驱
/dev/md[0-31]软raid设备
/dev/loop[0-7]本地回环设备
/dev/ram[0-15]内存
/dev/null无限数据接收设备,相当于黑洞
/dev/zero无限零资源
/dev/tty[0-63]虚拟终端
/dev/ttyS[0-3]串口
/dev/lp[0-3]并口
/dev/console控制台
/dev/fb[0-31]framebuffer
第9页共9页
/dev/cdrom=>/dev/hdc
/dev/modem=>/dev/ttyS[0-9]
/dev/pilot=>/dev/ttyS[0-9]
/dev/random随机数设备
/dev/urandom随机数设备
二、论述shell的基本工作原理。
LinuxShell工作原理
Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序。它不
属于内核部分,而是在核心之外,以用户态方式运行。
其基本功能是解释并执行用户打入的各种命令,实现用户与Linux核心的接口。
系统初启后,核心为每个终端用户建立一个进程去
执行Shell解释程序。它的执行过程基本上按如下步骤:
(1)读取用户由键盘输入的命令行。
(2)分析命令,以命令名作为文件名,并将其它参数改造为系统调用execve()
内部处理所要求的形式。
(3)终端进程调用fork()建立一个子进程。
(4)终端进程本身用系统调用wait4()来等待子进程完成(如果是后台命令,
则不等待)。当子进程运行时调用execve(),
子进程根据文件名(即命令名)到目录中查找有关文件(这是命令解释程序构
成的文件),将它调入内存,执行这个程序(解释这条命令)。
(5)如果命令末尾有&号(后台命令符号),则终端进程不用系统调用wait4()
等待,立即发提示符,让用户输入下一个命令,转⑴。
如果命令末尾没有&号,则终端进程要•直等待,当子进程(即运行命令的进程)
完成处理后终止,向父进程(终端进程)报告,
此时终端进程醒来,在做必要的判别等工作后,终端进程发提示符,让用户输
入新的命令,重复上述处理过程。
第10页共10
右
Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接
口。它是命令语言、命令解释程序及程序设计语言的统称。
shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一
个球体的中心,shell就是围绕内核的外层。
当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。
shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell
也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先
解释然后传给Linux核心。
有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一
些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的
单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单
独的程序。
shell首先检查命令是否是内部命令,若不是再检查是否是一个应用程序
(这里的应用程序可以是Linux本身的实用程序,如1s和rm,也可以是购买
的商业程序,如xv,或者是自由软件,如emacs)。然后shell在搜索路径里
寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列表)。如果
键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显
示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为
系统调用并传给Linux内核。
shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell
程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、
数组和程序控制结构。shell编程语言简单易学,任何在提示符中能键入的命
令都能放到一个可执行的shell程序中。
当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进
程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),
对普通用户用“$”作提示符,对超级用户(root)用作提示符。
一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。
shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕
上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常
结束之前,中止它的执行)。
第11页共11页
当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文
件结束符(EOF)(按ctrl+d实现),结束登录。
三、结合程序实例详细论述常用的5种进程通信方式。
linux使用的进程间通信方式:(1)管道(pipe)(2)信号(signal)(3)
消息队列(4)共享内存(5)信号量
]、管道通信
普通的;inuxshell都允许重定向,而重定向使用的就是管道。例如:
pslgrepvsftpd.管道是单向的、先进先出的、无结构的、固定大小的字节
流,它把一个进程的标准输出和另•个进程的标准输入连接在一起。写进
程在管道的尾端写入数据,读进程在管道的道端读出数据。数据读出后将
从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流
控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。
同样,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据
之前,写进程将一直阻塞。管道主要用于不同进程间通信。
管道的创建
fifowrite,c
ttinclude<sys/types.h>
Sinclude<sys/stat.h>
Sinclude<errno.h>
ttinclude<fcntl.h>
Sinclude<stdio.h>
Sinclude<stdlib.h>
Sinclude<string.h>
#defineFIFO_SERVER〃/tmp/myfifo〃
main(intargc,char**argv)
(
intfd;
charwbuf[100];
intnwrite;
/*打开管道*/
fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
if(argc==l)
(
printf(/zPleasesendsomething'n");
第12页共12
右
exit(-1);
strcpy(w_buf,argv[1]);
/*向管道写入数据*/
if((r)write=write(fd,w_buf,100))==-l)
(
if(errno==EAGAIN)
printf(Z/TheFIFOhasnotbeenreadyet.Pleasetry
later\n,z);
)
else
printf("'write%stotheFIF0\n,z,wbuf);
fifo_read.c
Sinclude<sys/types.h>
Sinclude<sys/stat.h>
ttinclude<errno.h>
Sinclude<fcntl.h>
Sinclude<stdio.h>
ttinclude<stdlib.h>
^include<string.h>
ttdefineFIFO〃/tmp/myfifo〃
main(intargc,char**argv)
(
charbuf_r[100];
intfd;
intnread;
/*创建管道*/
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
printf(z,cannotcreatefifoserver\n,z);
printf("'Preparingforreadingbytes...\n〃);
memset(buf_r,0,sizeof(buf_r));
第13页共13
右
/*打开管道*/
fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);
if(fd==-l)
(
perror("open");
exit(1);
)
while(1)
(
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fd,buf_r,100))==-l)
(
if(errno==EAGAIN)
printf(z,nodatayet\n");
)
printf("read%sfromFIF0\n”,buf_r);
sleep(1);
)
pause。;/*暂停,等待信号*/
uniink(FIFO);//删除文件
2、信号
信号概述
信号是软件中断。。它用于在一个或多个进程之间传递异步信号。很多条件可
以产生一个信号。
A、当用户按某些终端键时,产生信号。在终端上按DELETE键通常产生中断信
号(SIGINT)o这是停止一个已失去控制程序的方法。
B、硬件异常产生信号:除数为0、无效的存储访问等等。这些条件通常由硬件
检测到,并将其通知内核。然后内核为该条件发生时正在运行的进程产生
适当的信号。例如,对于执行一个无效存储访问的进程产生一个SIGSEGV。
C、进程用kill(2)函数可将信号发送给另一个进程或进程组。自然,有些限制:
接收信号进和发送信号进程的所有都必须相同,或发送信号进程的的所有
者必须是超级用户。
D、用户可用Kill(ID值)命令将信号发送给其它进程。此程序是Kill函数的
界面。常用此命令终止一个失控的后台进程。
E、当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号。这里
并不是指硬件产生条件(如被0除),而是软件条件。例如SIGURG(在网
第14页共14
右
络连接上传来非规定波特率的数据)、SIGPIPE(在管道的读进程已终止后
一个进程写此管道),以及SIGALRM(进程所设置的闹钟时间已经超时)。
内核为进程生产信号,来响应不同的事件,这些事件就是信号源。主要信号
源如下:
(1)异常:进程运行过程中出现异常;
(2)其它进程:一个进程可以向另一个或一组进程发送信号;
(3)终端中断:Ctrl-c,Ctro-\等;
(4)作业控制:前台、后台进程的管理;
(5)分配额:CPU超时或文件大小突破限制;
(6)通知:通知进程某事件发生,如I/O就绪等;
(7)报警:计时器到期;
Linux中的信号
1、SIGHUP2、SIGINT(终止)3、SIGQUIT(退出)4、SIGILL
5、SIGTRAP6、SIGIOT7、SIGBUS8、SIGFPE9、SIGKILL
10、SIGUSER11、SIGSEGVSIGUSER12、SIGPIPE13、SIGALRM
14、SIGTERM15、SIGCHLD16、SIGCONT17、SIGSTOP18、SIGTSTP
19、SIGTTIN20、SIGTTOU21、SIGURG22、SIGXCPU23、SIGXFSZ
24、SIGVTALRM25、SIGPROF26、SIGWINCH27、SIGIO28、SIGPWR常用
的信号:
SIGHUP:从终端上发出的结束信号;
SIGINT:来自键盘的中断信号(Ctrl+c)
SIGQUIT:来自键盘的退出信号;
SIGFPE:浮点异常信号(例如浮点运算溢出);
SIGKILL:该信号结束接收信号的进程;
SIGALRM:进程的定时器到期口寸,发送该信号;
SIGTERM:kill命令生出的信号;
SIGCHLD:标识子进程停止或结束的信号;
SIGSTOP:来自键盘(Ctrl-Z)或调试程序的停止扫行信号
可以要求系统在某个信号出现时按照下列三种方式中的一种进行操作。
(1)忽略此信号。大多数信号都可使用这种方式进行处理,但有两种信号却决
不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的,原
因是:它们向超级用户提供一种使进程终止或停止的可靠方法。另外,如
果忽略某些由硬件异常产生的信号(例如非法存储访问或除以0),则进
程的行为是示定义的。
(2)捕捉信号。为了做到这一点要通知内核在某种信号发生时,调用一个用户
函数。在用户函数中,可执行用户希望对这种事件进行的处理。如果捕捉
到SIGCHLD信号,则表示子进程已经终止,所以此信号的捕捉函数可以调
用waitpid以取得该子进程的进程ID以及它的终止状态。
第15页共15
右
(3)执行系统默认动作。对大多数信号的系统默认动作是终止该进程。每一个
信号都有一个缺省动作,它是当进程没有给这个信号指定处理程序时,内
核对信号的处理。有5种缺省的动作:
(1)异常终止(abort):在进程的当前目录下,把进程的地址空间内容、寄存
器内容保存到一个叫做core的文件中,而后终止进程。
(2)退出(exit):不产生core文件,直接终止进程。
(3)忽略(ignore):忽略该信号。
(4)停止(stop):挂起该进程。
(5)继续(contiune):如果进程被挂起,刚恢复进程的动行。否则,忽略信
号。信号的发送与捕捉
ki11()和raise()
kill。不仅可以中止进程,也可以向进程发送其他信号。与kill函数不同的是,
raise()函数运行向进程自身发送信号#include〈sys/types.h>
#include<signal.h>
intkill(pid_tpid,intsigno);
intraise(intsigno);
两个函数返回:若成功则为0,若出错则为kill的pid参数有四种不同的
情况:
(1)pid>0将信号发送给进程ID为pid的进程。
(2)pid==0将信号发送给其进程组ID等于发送进程的进程组ID,而且发送进
程有许可权向其发送信号的所有进程。
(3)pid<0将信号发送给其进程组ID等于pid绝对值,而且发送进程有许可
权向其发送信号的所有进程。如上所述一样,“所有进程”并不包括系统
进程集中的进程。
(4)pid==TPOSIX.1未定义种情况kill,c#include<stdio.h>
例子如下:
Sinclude<signal.h>
#include<stdio.h>
Sinclude<stdlib.h>
voidmy_func(intsign_no)
(
if(sign_no==SIGINT)
printf(,?IhavegetSIGINT'n");
elseif(sign_no==SIGQUIT)
printf(Z,IhavegetSIGQUIT'n");
)
intmainO
(
printf(/zWaitingforsignalSIGINTorSIGQUIT\n");
第16页共16
右
/*注册信号处理函数*/
signal(SIGINT,my_func);
signal(SIGQUIT,my_func);
pause();
exit(0);
)
3、消息队列
消息队列用于运行于同一台机器上的进程间通信,它和管道很相似,是一个在
系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出
现。消息链表中节点的结构用msg声明。
例子如下:
ttinclude<sys/types.h>
#include<sys/msg.h>
tiinclude<unistd.h>
structmsg_buf
(
intmtype;
chardata[255];
);
intmainO
(
key_tkey;
intmsgid;
intret;
structmsg_bufmsgbuf;
key=ftok(〃/tmp/2〃,'a');
printfC'key=[%x]\n〃,key);
msgid=msgget(key,IPC_CREAT10666);/*通过文件对应*/
if(msgid==-l)
(
printf(''createerror\nz,);
return-1;
)
第17页共17
msgbuf.mtype=getpid();
strcpy(msgbuf.data,z,testhaha");
ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);
if(ret==-l)
{
printf(z/sendmessageerr\n");
return-1;
)
memset(&msgbuf,0,sizeof(msgbuf));
ret=msgrcv(msgid,femsgbuf,sizeof(msgbuf.data),getpidO,IPC_NOWAIT
);
if(ret==-l)
(
printf("recvmessageerr\n");
return-1;
)
printf(z/recvmsg=[%s]\nz/,msgbuf.data);
)
4、共享内存
共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在
不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这
块内存区进行读写。
得到共享内存有两种方式:映射/dev/mem设备和内存映像文件。前一种方式不
给系统带来额外的开销,但在现实中并不常用,因为它控制存取的将是实
际的物理内存,在Linux系统下,这只有通过限制Linux系统存取的内存
才可以做到。常用的方式是通过shmXXX函数族来实现利用共享内存进行
存储的。
首先要用的函数是shmget,它获得一个共享存储标识符。
#include<sys/types.h>
Sinclude<sys/ipc.h>
#include<sys/shm.h>
intshmget(key_tkey,intsize,intflag);
这个函数有点类板malloc函数,系统按照请求分配size大小的内存用作共享
内存。Linux系统内核中每个IPC结构都有的一个非负整数的标识符,这
样对一个消息队列发送消息时只要引用标识符就可以了。这个标识符是内
第18页共18
右
核由IPC结构的关键字得到的。这个关键字,就是上面第一个函数的key。
数据类型key_t是在头文件sys/types.h中定义的,它是一个长整形的数
据。当共享内存创建后,其余进程可以调用shmat()将其连
接到自身的地址空间中。
void*shmat(intshmid,void*addr,intflag);
shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么
方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地
址,进程可以对此进程进行读写操作。
例子如下:
ttinclude<stdlib.h>
ttinclude<stdio.h>
Sinclude<string.h>
ttinclude<errno.h>
Sinclude<unistd.h>
Sinclude<sys/stat.h>
Sinclude<sys/types.h>
Sinclude<sys/ipc.h>
Sinclude<sys/shm.h>
#definePERMS_IRUSR|S_IWUSR
/*共享内存*/
intmain(intargc,char**argv)
(
intshmid;
char*p_addr,*c_addr;
if(argc!=2)
(
fprintf(stderr,z,Usage:%s\n\az,,argv[0]);
exit(1);
)
/*创建共享内存*/
if((shmid=shmget(IPC_PRIVATE,1024,PERM))=1)
(
fprintf(stderr,^CreateShareMemory
Error:%s\n\az,,strerror(errno));
exit(1);
第19页共19
右
/*创建子进程*/
if(fork())//父进程写
(
p_addr=shmat(shmid,0,0);
memset(p_addr,'\0",1024);
strncpy(p_addr,argv[l],1024);
wait(NULLr//释放资源,不关心终止状态
exit(0);
)
else//子进程读
(
sleep(l);//暂停1秒
c_addr=shmat(shmid,0,0);
printf(z,Clientget%s\n',c_addr);
exit(0);
)
)
5、信号量
信售量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的
应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数
器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了
获得共享资源,进程需要执行下列操作:
(1)测试控制该资源的信号量。
(2)若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。(3)
若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量
值大于0,进程被唤醒,转入步骤(1)。
(4)当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有
进程正在睡眠等待此信号量,则唤醒此进程。
例子如下:
intopen_semaphore_set(key_tkeyval,intnumsems)
(
intsid;
if(Inumsems)
return(-1);
if((sid=semget(mykey,numsems,IPC_CREAT0660))==T)
{
return(-1);
第20页共20
右
return(sid);
};、
semopO
系统调用:semopO;调用原型:intsemop(intsemid,struct
sembuf*sops,unsignednsops);
返回值:0,如果成功。-1,
如果失败:errno=E2BIG(nsops大于最大的ops数目
四、对进程与线程的区别进行分析。
对于操作系统而言,进程是核心之核心,整个现代操作系统的
根本,就是以进程为单位在执行任务。系统的管理架构也是基于进
程层面的。在按下电源键之后,计算机就开始了复杂的启动过程,
此处有一个经典问题:当按下电源键之后,计算机如何把自己由静
止启动起来的?本文不讨论系统启动过程,请读者自行科普。操作
系统启动的过程简直可以描述为上帝创造万物的过程,期初没有世
界,但是有上帝,是上帝创造了世界,之后创造了万物,然后再创
造了人,然后塑造了人的七情六欲,再然后人类社会开始遵循自然
规律繁衍生息。。。操作系统启动进程的阶段就相当于上帝造人的
阶段。本文讨论的全部内容都是“上帝造人”之后的事情。第一个
被创造出来的进程是0号进程,这个进程在操作系统层面是不可见
的,但它存在着。0号进程完成了操作系统的功能加载与初期设定,
第21页共21
右
然后它创造了1号进程(init),这个1号进程就是操作系统的“耶
稣”。1号进程是上帝派来管理整个操作系统的,所以在用pstre
e查看进程树可知,1号进程位于树根。再之后,系统的很多管理
程序都以进程身份被1号进程创造出来,还创造了与人类沟通的桥
梁一一shello从那之后,人类可以跟操作系统进行交流,可以编
写程序,可以执行任务。。。
而这一切,都是基于进程的。每一个任务(进程)被创建时一,系
统会为他分配存储空间等必要资源,然后在内核管理区为该进程创
建管理节点,以便后来控制和调度该任务的执行。
进程真正进入执行阶段,还需要获得CPU的使用权,这一切都是操
作系统掌管着,也就是所谓的调度,在各种条件满足(资源与CPU
使用权均获得)的情况下,启动进程的执行过程。
除CPU而外,一个很重要的资源就是存储器了,系统会为每个进程
分配独有的存储空间,当然包括它特别需要的别的资源,比如写入
时外部设备是可使用状态等等。有了上面的引入,我们可以对进程
做一个简要的总结:
进程,是计算机中的程序关于某数据集合上的一次运行活动,是系
统进行资源分配和调度的基本单位,是操作系统结构的基础。它的
执行需要系统分配资源创建实体之后,才能进行。
第22页共22
右
随着技术发展,在执行一些细小任务时,本身无需分配单独资
源时(多个任务共享同一组资源即可,比如所有子进程共享父进程
的资源),进程的实现机制依然会繁琐的将资源分割,这样造成浪
费,而且还消耗时间。后来就有了专门的多任务技术被创造出来一
一线程。
线程的特点就是在不需要独立资源的情况下就可以运行。如此一来
会极大节省资源开销,以及处理时间。
1.好了,前面的一段文字是简要引入两个名词,即进程和线程。本
文讨论目标是解释清楚进程和线程的区别,关于二者的技术实现,
请读者查阅相关资料。
下面我们开始重点讨论本文核心了。从下面几个方面阐述进程
和线程的区别。
1).二者的相同点
2).实现方式的差异
3).多任务程序设计模式的区别
4).实体间(进程间,线程间,进线程间)通信方式的不同
5).控制方式的异同
6).资源管理方式的异同
第23页共23
右
7).个体间辈分关系的迥异
8).进程池与线程池的技术实现差别
接下来我们就逐个进行解释。
1).二者的相同点
无论是进程还是线程,对于程序员而言,都是用来实现多任务
并发的技术手段。二者都可以独立调度,因此在多任务环境下,功
能上并无差异。并且二者都具有各自的实体,是系统独立管理的对
象个体。所以在系统层面,都可以通过技术手段实现二者的控制。
而且二者所具有的状态都非常相似。而且,在多任务程序中,子进
程(子线程)的调度一般与父进程(父线程)平等竞争。
其实在Linux内核2.4版以前,线程的实现和管理方式就是完
全按照进程方式实现的。在2.6版内核以后才有了单独的线程实
现。
第24页共24
右
嵋状态图
2).实现方式的差异
进程是资源分配的基本单位,线程是调度的基本单位。
这句经典名言已流传数十年,各种操作系统教材都可见此描述。
确实如此,这就是二者的显著区别。读者请注意“基本”二字。相
信有读者看到前半句的时候就在心里思考,“进程岂不是不能调
第25页共25
右
度?”,非也!进程和线程都可以被调度,否则多进程程序该如何
运行呢!
只是,线程是更小的可以调度的单位,也就是说,只要达到线程的
水平就可以被调度了,进程自然可以被调度。它强调的是分配资源
时的对象必须是进程,不会给一个线程单独分配系统管理的资源。
若要运行一个任务,想要获得资源,最起码得有进程,其他子任务
可以以线程身份运行,资源共享就行了。
简而言之,进程的个体间是完全独立的,而线程间是彼此依存
的。多进程环境中,任何一个进程的终止,不会影响到其他进程。
而多线程环境中,父线程终止,全部子线程被迫终止(没有了资源)。
而任何一个子线程终止一般不会影响其他线程,除非子线程执行了
exit。系统调用。任何一个子线程执行exit。,全部线程同时灭
亡。
其实,也没有人写出只有线程而没有进程的程序。多线程程序
中至少有一个主线程,而这个主线程其实就是有main函数的进程。
它是整个程序的进程,所有线程都是它的子线程。我们通常把具有
多线程的主进程称之为主线程。
从系统实现角度讲,进程的实现是调用fork系统调用:
pidtfork(void);
第26页共26
右
线程的实现是调用clone系统调用:
intclone(int(*fn)(void*),void*child_stack,intf
lags,void*arg,
/*pidt*ptid,structuserdesc*tls,pidt*ctid*/
);
其中,fork。是将父进程的全部资源复制给了子进程。而线程
的clone只是复制了一小部分必要的资源。在调用clone时可以通
过参数控制要复制的对象。可以说,fork实现的是clone的加强
完整版。当然,后来操作系统还进一步优化fork实现一一写时复
制技术。在子进程需要复制资源(比如子进程执行写入动作更改父
进程内存空间)时才复制,否则创建子进程时先不复制。
实际中,编写多进程程序时采用fork创建子进程实体。而创建
线程时并不采用clone系统调用,而是采用线程库函数。常用线程
库有Linux-Native线程库利POSIX线程库。其中应用最为广泛的
是POSIX线程库。因此读者在多线程程序中看到的是pthread_cre
ate而非cloneo
我们知道,库是建立在操作系统层面上的功能集合,因而它的功能
都是操作系统提供的。由此可知,线程库的内部很可能实现了clo
第27页共27
右
ne的调用。不管是进程还是线程的实体,都是操作系统上运行的
实体。
最后,我们说一下vfork()o这也是一个系统调用,用来创
建一个新的进程。它创建的进程并不复制父进程的资源空间,而是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030文化活动行业品牌推广方案创新研究及市场营销策略优化规划分析报告
- 互联网金融风险防控实操方案
- 老旧建筑加固改造技术方案指南
- 新课程背景下小学教学常规提升方案
- 医疗废水处理技术及管理方案
- 住宅楼栏杆安装施工方案
- 国际会议政务接待综合管理方案
- 市政工程施工监理方案指导
- 成本管控信息化的成本责任体系
- 成本效益分析:医院管控目标核心维度
- 电力线通信技术
- 人工流产手术知情同意书
- 教师三笔字培训课件
- 中国医药行业中间体出口全景分析:破解政策难题深挖全球红利
- 河南省百师联盟2025-2026学年高一上12月联考英语试卷(含解析含听力原文及音频)
- 污水管道更换工程施工方案
- 租户加装充电桩免责补充合同(房东版)
- 甘肃省天水市2024-2025学年九年级上学期期末考试物理试题(含答案)
- 2025年佛山市均安镇专职消防队招聘消防员5人备考题库及1套参考答案详解
- 2026年海南卫生健康职业学院单招职业技能考试题库参考答案详解
- 法制副校长课件
评论
0/150
提交评论