资源预览内容
第1页 / 共71页
第2页 / 共71页
第3页 / 共71页
第4页 / 共71页
第5页 / 共71页
第6页 / 共71页
第7页 / 共71页
第8页 / 共71页
第9页 / 共71页
第10页 / 共71页
亲,该文档总共71页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第八章 操作系统环境下的编程及应用 第八章 操作系统环境下的编程及应用 8.1 应用程序编程接口概述 应用程序编程接口概述 8.2 进程间通讯实现方法与实例进程间通讯实现方法与实例 8.3 线程编程及实现方法线程编程及实现方法 第八章 操作系统环境下的编程及应用 8.1 应用程序编程接口概述应用程序编程接口概述 应用程序编程接口(Application Programming Intertace, 简称 API)是由操作系统支持的函数定义、参数定义和消息 格式的集合。 应用程序可借助API函数处理系统提供的功能。 Windows API函数提供了Windows所支持的所有系统服务的 功能。 第八章 操作系统环境下的编程及应用 标准的Win32 API函数总体上可以分成七类, 分别为: (1) 窗口管理。 (2) 窗口通用控制。 (3) Shell特性。 (4) 图形设备接口。 (5) 系统服务。 (6) 国际特性。 (7) 网络服务。 第八章 操作系统环境下的编程及应用 8.2 进程间通讯实现方法与实例进程间通讯实现方法与实例 8.2.1 管道管道 了解管道的一个直观的例子是在命令中使用管道符,例如命 令: ls -1 | grep linux | more 就使用了两个管道符,grep的输入来自于ls的输出, 而grep的输 出又作为more命令的输入使用。该命令的含义是在当前目录中查 找名字中包含“linux”的目录或者文件,然后分屏显示。 管道可以分成两类:无名管道(简称管道)和FIFO(也称 为命名管道)。二者之间主要的区别在于无名管道只能用于父、 子进程之间的通讯, 而FIFO则可以用于任何进程之间的通讯。 第八章 操作系统环境下的编程及应用 1. 无名管道 无名管道 所有的UNIX系统都支持管道的通讯机制。 管道有两种限制: (1) 管道是半双工的, 数据只能单向流动; (2) 管道只能在父子进程之间使用。 管道由系统调用pipe( )产生, 该函数的语法为 int pipe(int fd2) 参数fd用来存放pipe( )创建的管道的句柄。 fd0用于读, fd 1用于写。 第八章 操作系统环境下的编程及应用 图8.1 父进程向子进程传递信息的管道 第八章 操作系统环境下的编程及应用 下面是一个使用管道实现子进程向父进程传递信息的例子: include include include int main(void) int fd2,nbytes; pid -t pid; char string =“Hello, world! n“; char readbuffer80; 第八章 操作系统环境下的编程及应用 pipe(fd); /*创建管道*/ if ( (pid = fork( ) = -1) /*创建子进程*/ perror(“fork“); exit(1); if (pid = 0) /*子进程*/ close(fd0); /*关闭管道读句柄*/ write(fd1,string,strlen(string); /*向管道中写入数据*/ -exit(0); 第八章 操作系统环境下的编程及应用 else/*父进程*/ close(fd1);/*关闭管道写句柄*/ nbytes = read(fd0,readbuffer,sizeof(readbuffer); /*从管道中读取数据*/ printf(“Received Strings: %sn“,readbuffer); return (0); 第八章 操作系统环境下的编程及应用 popen函数原型为 FILE *popen(const char *cmdstring, const char *type) 该函数首先创建一个管道,再执行fork创建一个子进程, 然后调用exec执行cmdstring指定的命令,并返回一个标准的文 件指针。 该文件指针根据type值进行定位:如果type是“r”, 则链接到cmdstring的标准输出上;如果type是“w”,则链接到 cmdstring的标准输入上。 第八章 操作系统环境下的编程及应用 下面的程序实现ls | more的功能: include int main(void) FILE *in -fp,*out -fp; char readbuffer80; if ( (in -fp = popen (“ls“,“r“) = NULL) ) perror(“popen“); exit(1); 第八章 操作系统环境下的编程及应用 if ( (out -fp = popen (“more“,“w“) = NULL) ) perror(“popen“); exit(1); while (fgets(readbuf, 80, in -fp) fputs(readbuf, out -fp); pclose(in -fp); pclose(out -fp); return (0); 第八章 操作系统环境下的编程及应用 2. FIFO 在系统shell中,我们可以使用下面的命令来创建命名管道: mknod FIFOname p mkfifo -m 0666 FIFOname 而在C语言中, 我们可以使用mknod函数或者makefifo函 数创建命名管道, 函数原型如下: int mknod( char *pathname, mode -t mode, dev -t dev ) int mkfifo( const char *pathname, mode -t mode ) 第八章 操作系统环境下的编程及应用 服务器端程序: FILE * in -file; char buffer80; in -file = fopen(“FIFOname“,“r“); if ( in -file = NULL ) perror(“fopen“); exit(1); fread(buffer, 1, 80, in -file); printf(“Data recieved from FIFO: %sn“, buffer); fclose(in -file); 第八章 操作系统环境下的编程及应用 客户端程序: FILE * out -file; char buffer80; out-file = fopen(“FIFOname“,“w“); if ( out-file = NULL ) perror(“fopen“); exit(1); sprintf(buffer,“Test data for named pipe!n“); fwrite(buffer, 1, 80, out -file); printf(“Data recieved from FIFO: %sn“, buffer); fclose(out-file); 第八章 操作系统环境下的编程及应用 命名管道只能用于同种文件系统中的进程之间的通讯,在 使用的过程中要注意其独立性问题,也就是说操作不能被其它 进程打断。一次独立操作可以传送的最大字节数在POSIX标准 中是在/usr/include/bits/posix1-lim.h中定义的: define -POSIX -PIPE -BUF 512 在Linux中,由/usr/include/linux/limits.h定义: define PIPE -BUF 4096 如果进行通讯的进程需要写入管道的数据超过这个限制, 就必须将其分割成几个独立的操作过程。 第八章 操作系统环境下的编程及应用 8.2.2 System V IPC机制机制 Unix System V中引入了三种新的IPC机制:消息队列 (Message Queue)、信号量(Semaphores)和共享内存 (Shared Memory)。这三种IPC机制有很多相似之处,你可 以使用ipcs命令来查看当前系统中这三种IPC的使用情况。 消息队列、 信号量和共享内存在系统中都有一个唯一的 标志符(标志符是一个非负、递增的数字,达到最大值时再 从0开始计数),内核根据这个标志符来区分这些IPC对象。 第八章 操作系统环境下的编程及应用 在程序中,我们需要使用关键字(key)来访问它们。 关键 字可以使用ftok系统调用来生成, 函数原型如下: key-t ftok( char *pathname, char proj ) 进行通讯的进程必须使用同一个关键字, 只要二者运 行的目录(由参数pathname指定)是相同的, 就可以保证 ftok产生的关键字相同。 第八章 操作系统环境下的编程及应用 ipc-perm结构的定义在linux/ipc.h中, 如下所示: struct ipc -perm - -kernel -key -t key; - -kernel -uid -t uid; - -kernel -gid -t gid; - -kernel -uid -t cuid; - -kernel -gid -t cgid; - -kernel -mode -t mode; unsigned short seq; 第八章 操作系统环境下的编程及应用 1. 消息队列 消息队列 消息队列把进程之间传递的消息(struct msg结构的数据) 以链表的形式组织在一起,进行通讯的写方进程经过权限认 定之后, 把需要传递的数据追加在队列的尾部,读方进程就 可以从该队列中读取需要的数据,从而实现多个进程之间的 通讯。 每个消息队列都有一个struct msqid -ds(在linux/msg.h 中定义)的结构和它相关,该结构反映消息队列的当前状态: 第八章 操作系统环境下的编程及应用 struct msqid -ds struct ipc -perm msg -perm; struct msg *msg -first;/* first message on queue,unused */ struct msg *msg -last;/* last message in queue,unused */ -kernel-time-t msg-stime; /* last msgsnd time */ -kernel-time-t msg-rtime; /* last msgrcv time */ -kernel-time-t msg-ctime; /* last change time */ unsigned long msg-lcbytes;/* Reuse junk fields for 32 bit */ unsigned long msg-lqbytes;/* ditto */ unsigned short msg-cbytes; /* current number of bytes on queue */ unsigned short msg-qnum; /* number of messages in queue */ unsigned short msg-qbytes; /* max number of bytes on queue */ -kernel-ipc-pid-t msg-lspid; /* pid of last msgsnd */ -kernel-ipc-pid-t msg-lrpid; /* last receive pid */ 第八章 操作系统环境下的编程及应用 和消息队列的使用有关的系统调用有三个:msgget、 msgsnd和msgrcv, 其函数原型如下: int msgget ( key -t key, int msgflg ) int ms
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号