linux I/O编程,用select()函数和无名管道机制实现

代码分析

  程序分析

//select.c
#include "select.h"
/*
 * comment:
 * pipe is used between two processes on the same computer.
 * */
#define TIMES 50
int main()
{
	int pipefds[2];
	int i;
	//int pipe(int fd[2]) 
	if( -1 == pipe( pipefds))
	{ 
		printf( "Error when create pipes\n");
	}
	else
	{
		pid_t pid = fork();
		//pid_t fork(void)
		if( 0 == pid)
		{// child
			printf( "child running\n");			   
			close( pipefds[0]);
            //子进程关闭读口,仅作写口
			for( i = 0; i < TIMES; ++ i)
			{
				write( pipefds[1], "I am a good boy!",\
						strlen( "I am a good boy!"));
				sleep(1);
			}
		}
		else
		{
			printf( "parent running\n");
			char buf[256];
			close( pipefds[1]);
            父进程关闭写口,仅作读口
			fd_set readfdset;// file descriptor set
			for( i = 0; i < TIMES; ++ i)
			{
				FD_ZERO( & readfdset);
				
				// add read file descriptor
				FD_SET( pipefds[0], & readfdset);	
				
				// add standard input
				FD_SET( 0, & readfdset);
				//select之前首先初始化
				//int select(int nfds, fd_set *readfds, fd_set *writefds,
				//  fd_set *exceptfds, struct timeval *timeout);
				select( pipefds[0]+1, & readfdset, NULL, NULL, NULL);
                //第二个参数:由select监视的读文件描述符集合
                //第三个参数:由select监视的写文件描述符集合
                //第四个参数:由select监视的异常处理文件描述符集合
                //第四个参数:timeout,NULL表示永远等待
				if( FD_ISSET( pipefds[0], & readfdset))
				{
					buf[ read(pipefds[0], buf, 256)] = '\0';
					printf( "Receive:%s\n", buf);
				}
				if( FD_ISSET( 0, & readfdset))
				{
					buf[ read( 0, buf, 256)] = '\0';
					printf( "Print:%s\n", buf);
				}
			}	//end for TIMES
			int status;
			wait( & status);
            //使父进程阻塞,直到一个子进程结束
		}	//end if pid
	}	//end if of creat pipee
	return 0;
}

执行结果

  子进程负责往缓冲区写,而父进程,把读口的文件描述符和标准输入加入监听集,用select监听,程序执行的结果是父进程一直等待子进程的写动作或者标准输入,循环50次。
执行结果