您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 人事档案/员工关系 > 第9章 Linux编程―信号函数
LinuxLinux操作系统操作系统•大工软件学院嵌入式系邱铁办公楼409Tel:87571521E_mail:qiutie@sohu.com第9章Linux编程—信号函数sleep(让进程暂停执行一段时间)alarm(设置信号传送闹钟)示例解析•#includeunistd.h•#includesignal.h•voidhandler(){•printf(hello\n);•}•main()•{•inti;•signal(SIGALRM,handler);•alarm(5);•for(i=1;i7;i++){•printf(sleep%d...\n,i);•sleep(1);•}•}kill(传送信号给指定的进程)续•错误代码•EINVAL参数sig不合法•ESRCH参数pid所指定的进程或进程组不存在•EPERM权限不够无法传送信号给指定进程pid_twait(int*status)•发出wait调用的进程进入睡眠直到它的一个子进程退出时或收到一个不能被忽略的信号时被唤醒。如果调用发出时,已经有退出的子进程(这时子进程的状态是僵死状态),该调用立即返回。其中调用返回时参数status中包含子进程退出时的状态信息。•WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED来判断后才使用此宏。示例解析•#includeunistd.h•#includesignal.h•#includesys/types.h•#includesys/wait.h•main()•{•pid_tpid;•intstatus;•if(!(pid=fork())){•printf(Hi,Iamchildprocess!\n);•sleep(10);•return;•}续•else{•printf(sendsignaltochildprocess(%d)\n,pid);•sleep(1);•kill(pid,SIGABRT);•wait(&status);•if(WIFSIGNALED(status))•printf(chileprocessreceivesignal%d\n,WTERMSIG(status));•}•}pause(让进程暂停直到信号出现)perror(打印出错误原因信息字符串)示例解析•#includestdio.h•main()•{•FILE*fp;•fp=fopen(/tmp/noexist,r+);•if(fp==NULL)perror(fopen);•}strerror返回错误原因的描述字符串示例解析•/*显示错误代码0至9的错误原因描述*/•#includestring.h•main()•{•inti;•for(i=0;i10;i++)•printf(%d:%s\n,i,strerror(i));•}mkfifo(建立命名管道)•表头文件•#includesys/types.h•#includesys/stat.h•定义函数intmkfifo(constchar*pathname,mode_tmode);续•函数说明•mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此umask值也会影响到FIFO文件的权限。mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。当使用open()来打开FIFO文件时,O_NONBLOCK旗标会有影响:•1、当使用O_NONBLOCK旗标时,打开FIFO文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO文件来读取,则写入的操作会返回ENXIO错误代码。•2、没有使用O_NONBLOCK旗标时,打开FIFO来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO文件来读取后才正常返回。续•返回值若成功则返回0,否则返回-1,错误原因存于errno中。•错误代码•EACCESS参数pathname所指定的目录路径无可执行的权限•EEXIST参数pathname所指定的文件已存在。•ENAMETOOLONG参数pathname的路径名称太长。•ENOENT参数pathname包含的目录不存在•ENOSPC文件系统的剩余空间不足•ENOTDIR参数pathname路径中的目录存在但却非真正的目录。•EROFS参数pathname指定的文件存在于只读文件系统内。示例解析•#includesys/types.h•#includesys/stat.h•#includefcntl.h•#defineFIFO/tmp/fifo•main()•{•charbuffer[80];•intfd;•unlink(FIFO);•mkfifo(FIFO,0666);续•if(fork()0){•chars[]=hello!\n;•fd=open(FIFO,O_WRONLY);•write(fd,s,sizeof(s));•close(fd);•}•else{•fd=open(FIFO,O_RDONLY);•read(fd,buffer,80);•printf(%s,buffer);•close(fd);•}•}pipe(建立管道)•表头文件#includeunistd.h•定义函数intpipe(intfiledes[2]);•函数说明•pipe()会建立管道,并将文件描述词由参数filedes数组返回。filedes[0]为管道里的读取端,filedes[1]则为管道的写入端。•返回值若成功则返回零,否则返回-1,错误原因存于errno中。•错误代码•EMFILE进程已用完文件描述词最大量•ENFILE系统已无文件描述词可用。•EFAULT参数filedes数组地址不合法。示例解析•/*父进程借管道将字符串“hello!\n”传给子进程并显示*/•#includeunistd.h•main()•{•intfiledes[2];•charbuffer[80];•pipe(filedes);•if(fork()0){•/*父进程*/•chars[]=hello!\n;•write(filedes[1],s,sizeof(s));•}•else{•/*子进程*/•read(filedes[0],buffer,80);•printf(%s,buffer);•}•}popen(建立管道I/O)•表头文件#includestdio.h•定义函数FILE*popen(constchar*command,constchar*type);•函数说明•popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh-c来执行参数command的指令。参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。续•返回值若成功则返回文件指针,否则返回NULL,错误原因存于errno中。•错误代码EINVAL参数type不合法。•注意事项•在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。示例解析•#includestdio.h•main()•{•FILE*fp;•charbuffer[80];•fp=popen(cat/etc/passwd,r);•fgets(buffer,sizeof(buffer),fp);•printf(%s,buffer);•pclose(fp);•}
本文标题:第9章 Linux编程―信号函数
链接地址:https://www.777doc.com/doc-5477488 .html