为用户编程终端控制和.ppt_第1页
为用户编程终端控制和.ppt_第2页
为用户编程终端控制和.ppt_第3页
为用户编程终端控制和.ppt_第4页
为用户编程终端控制和.ppt_第5页
已阅读5页,还剩69页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第七讲 为用户编程:终端控制和信号,主要内容,软件工具与用户程序 读取和修改终端驱动程序的设置 非阻塞输入 用户输入的超时 信号 fcntl及signal系统调用,与终端有关的程序,用户常用的程序例如vi、emacs及许多游戏程序经常要有终端进行交互 它们设置终端驱动程序的击键和输出处理方式 用户经常用到的几种用户终端设置: 立即响应击键事件 有限的输入集 输入的超时 屏蔽Ctrl-C,终端驱动程序的模式,/*rotate.c*/ #include #include int main() int c; while ( (c=getchar()!=EOF) if (c=z) c=a else i

2、f (islower(c) c+; putchar(c); ,规范模式:缓冲和编辑,使用默认设置运行该程序(-退格键) $ gcc rotate.c -o rotate $./rotate abx- cd bcde efg C $,输入的内容及程序所得到的内容,rotate程序,终端驱动程序,显示器及键盘,标准输入处理的特征,程序未得到输入的x,因为删除了它 击键的同时字符显示在屏幕上,但直到按了回车,程序才接收到输入 C键结束输入并终止程序 程序rotate并不负责这些事情,对于输入的缓冲、回显、编辑和控制键处理都由驱动程序完成 标准输入处理的这些特征被启动时,将终端连接称为规范模式,非规范

3、处理,$stty -icanon;./rotate abbcxy?cdde effggh $stty icanon stty -icanon命令关闭驱动程序中的规范模式处理 非规范模式没有缓冲,输入字母a,驱动程序跳过缓冲层,字符直接送到程序,然后程序显示字符b 用户输入未缓冲可能会带来麻烦,如果用户想修改输入时,此时将无法修改,终端模式小结-规范模式,是用户常见的模式 输入的字符保存在缓冲区 接收到回车键时才将其中内容发送到程序 缓冲功能使驱动程序可实现编辑功能,例如删除字符、单词或者行 可通过命令stty或者系统调用tcsetattr修改执行上述操作的特定键,终端模式小结-非规范模式,缓冲

4、和编辑功能被关闭时,连接被称为处于非规范模式 设备驱动器仍然进行特定字符的处理,例如Ctrl-C及换行符及回车符之间的转换 删除单词、字符及终止编辑键将不具有特殊 含义而是被视作常规的数据输入,终端模式小结-raw模式,每个处理步骤都被一个独立的位控制,例如ISIG位控制Ctrl-C是否用于终止一个程序 程序可随意关闭所有这些处理步骤 当所有处理都被关闭后,驱动程序将输入直接传递给程序。这种模式就称为raw模式 stty raw命令,编写一个用户程序:play_again.c,play_again.c的逻辑: 对用户显示提示问题 接受输入 如果是y返回0 如果是n返回1 第一个play_aga

5、in0.c程序,play_again0.c的不足,必须先按 回车,程序才能接受到数据 当用户按回车键时,程序接收整行的数据对其进行处理,例如 Do you want another transaction(y/n)? sure thing,s u r e t h i n g,改进方法,首先关闭规范输入,使得程序能够在用户敲键的同时得到输入的字符 set_crmode() struct termios ttystate; tcgetattr( 0, /* install settings*/,tty_mode(int how),static struct termios original_mod

6、e; if ( how = 0 ) tcgetattr(0, ,程序的主要过程,首先调用tty_mode(0)函数保存当前终端的设置信息 set_crmode()函数首先将终端置于一个字符接一个字符的模式 然后调用函数显示一个提示符,并获得一个响应 最后调用tty_mode(1)函数还原终端的设置,将终端置入字符输入模式包括两部分工作: 将ICANON位关闭 将控制字符数组中的VMIN下标元素置一,VMIN的值告诉驱动程序一次可以读取多少个字符,编译执行play_again1程序,此时,程序可以直接接收和处理字符而不用等待回车键 但对每个非法字符都提示错误信息,可能比较烦 可关闭回显模式,丢掉

7、不需要的字符,直到得到可接收的字符为止 在set_crmode函数中加入语句 ttystate.c_lflag printf(%s (y/n)?, question);/* ask*/ fflush(stdout);/* force output*/ while ( 1 ) sleep(SLEEPTIME);/* wait a bit*/ input = tolower(get_ok_char(); /* get next chr */ if ( input = y ) return 0; if ( input = n ) return 1; if ( maxtries- = 0 )/* ou

8、tatime?*/ return 2;/* sayso*/ BEEP; ,实验结果,在输入后,程序会延时一会儿 如果长时间不输入,程序也会退出,fflush(out)函数,终端驱动对于输出也是一行行缓冲的 直到它收到一个换行符或者程序试图从终端读取数据时才会进行输出 而此时getchar被延迟读入,因此通过该函数将提示信息输出到屏幕上,否则用户将看不到提示信息。,Ctrl -C,执行上述程序时,如果输入Ctrl-C则程序终止运行,同时,也终止了整个登录会话 原因是什么呢?,Ctrl -C,设置O_NDELAY 设置crmode 显示提示符 等待用户输入 用户输入 恢复tty设置 恢复fcntl

9、标志 退出,程序流程,Ctrl C,进程被终止,进程正常退出时流向,Ctrl -C,程序接收到Ctrl-C后,会立即退出,此时,无法执行重置启动程序的代码 返回shell并从用户获得命令行时,终端仍处于非阻塞模式。 shell调用read获取命令行,但是因为处于非阻塞状态,read立即返回0. 这时shell程序就退出 原因总结:程序结束时,文件描述符处于一个错误的状态。,信号,Ctrl-C中断当前运行的程。这个中断由内核的信号机制产生 Ctrl-C的过程: 用户输入Ctrl-C 驱动程序收到字符 匹配VINTR和ISIG的字符被开启 驱动程序调用信号系统 信号系统发送SIGINT到进程 进程

10、收到SIGINT 进程消亡,什么是信号,信号是由单个词组成的消息,例如红绿灯所发出的信息 Ctrl-C时,内核向当前运行的进程发送中断信号 每个信号都有一个数字编码。中断信号编码通常是2,信号的来源,信号来自内核 生成信号的请求来自3个地方: 用户-通过输入Ctrl-C、 Ctrl-等请求内核产生信号 内核-进程执行出错时,内核向进程发送一个信号,例如非法段访问、浮点数溢出等,也可通知进程特定事件的发生。 进程-通过系统调用kill给另一个进程发送信号。进程之间可通过信号通信,同步与异步信号,由进程的某个操作产生的信号称为同步信号,例如被零除 用户击键这样的进程外的事件引起的信号称为异步信号,

11、信号列表,信号编号及其名字可在/usr/include/signal.h文件中找到,例如SIGINT为中断信号,SIGQUIT退出信号,SIGSEGV非法段访问信号 可以使用信号消灭一个进程,也有办法保护自己不被杀死,进程处理信号的方法,进程通过signal系统调用告诉内核如何处理信号 进程有3个选择: (1)接受默认处理 SIGINT默认处理为消亡,进程通过系统调用signal(SIGINT,SIG_DFL)恢复默认处理 (2)忽略信号 signal(SIGINT,SIG_IGN)系统调用告诉内核忽略该信号,进程处理信号的方法,(3)调用一个函数,这是3种方法中最强大的一个。 例如在play

12、_again3程序中,当用户输入Ctrl-C时,程序收到信号后执行一个恢复设置的函数就不会发生上述情况了 程序能够告诉内核,当信号来时调用哪个函数,signal(SIGINT,function); 信号到来时所调用的函数称为信号处理函数,signal系统调用,signal系统调用,其中action可以是函数名也可以是如下两种特殊值之一: SIG_IGN,忽略信号 SIG_DFL 将信号恢复为默认处理 signal返回前一个处理函数。值为指向该函数的指针,信号处理的例子sigdemo1.c,#include #include main() voidf(int);/* declare the ha

13、ndler*/ inti; signal( SIGINT, f );/* install the handler*/ for(i=0; i5; i+ )/* do something else*/ printf(hellon); sleep(1); void f(int signum)/* this function is called */ printf(OUCH!n); ,信号处理过程,main() signal(SIGINT,f); for(i=0;i5;i+) printf(“hellon”); sleep(1); ,正常控制流,信号,函数f() printf(“OUCH”); ,si

14、gdemo1.c执行结果,hello hello hello hello COUCH! hello,忽略信号sigdemo2.c,#include #include main() signal( SIGINT, SIG_IGN ); printf(you cant stop me!n); while( 1 ) sleep(1); printf(hahan); ,sigdemo2.c程序执行结果,you cant stop me! haha haha Chaha haha Chaha haha 退出,sigdemo2.c调用signal忽略中断信号,可以随意按Ctrl-C而不会对程序产生影响,s

15、ignal(SIGINT,SIG_IGNT),作业,6.10,处理多个信号,当有多个信号到达进程时,该如何处理?,1.捕鼠器问题,信号处理函数有点像捕鼠器 早期版本中,在每次捕获之后,都必须重设它们。例如 void handler(int s) signal(SIGINT,handler); ,1.捕鼠器问题,即使设置的速度非常快,它还是需要时间 触发处理函数及重新设置完成之前,有新的信号或者老鼠溜走 这一脆弱的间隙使得原有的信号处理不可靠,因此称为不可靠的信号,处理多个信号,第二个信号打断第一个信号的处理 第二个信号被阻塞 返回信号处理的地方是否要重新开始? 信号的优先级?,进程的多个信号,

16、处理函数每次使用之后都要禁用吗? 如果SIGY消息在进程处理SIGX消息时到达会发生什么? 如果进程还在处理前一个SIGX时,第二个SIGX又到来会发生什么事情呢?第三个呢? 如果信号到来时,程序正在处理getchar或者read之类的输入而阻塞,那会如何呢?,测试多个信号sigdemo3.c程序,signal( SIGINT, inthandler );/* set handler */ signal( SIGQUIT, quithandler );/* set handler */ do printf(nType a messagen); nchars = read(0, input, (

17、INPUTLEN-1); if ( nchars = -1 ) perror(read returned an error); else inputnchars = 0; printf(You typed: %s, input); while( strncmp( input , quit , 4 ) != 0 ); ,void inthandler(int s) printf( Received signal %d . waitingn, s ); sleep(2); printf( Leaving inthandler n); void quithandler(int s) printf(

18、Received signal %d . waitingn, s ); sleep(3); printf( Leaving quithandler n); ,执行结果,Type a message hello you typed:hello Type a message C Received signal 3.Received signal 2.Leaving inthandler Leaving quithandler,各种实验,(1)输入C C C C (2) C C (3)helloC Return (4)hello Return C (5) helloC,第一种情况,不可靠的信号 若两个SIGINT信号杀死了进程,则系统是不可靠的信号 若未杀死进程,则处理函数在被调用后还有作用 现代信号处理机制允许在两者之间选择 默认情况下,为后者 第一次实验的结果为:信号函数执行了两次,后面的两次函数丢失,第二种情况:SIGY打断SIGX的处理 函数,接连按下C和时程序先跳到inthandler,然后跳到quithandler,然后再回到inthandler,最后回到主循环 第二种情况的实验:接收到后,程序进入quithandler程序,接收到C后,进入inthandler程序,最后返回到quithandler

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论