Concurrent Programming with I/O Multiplexing

Suppose you are asked to write an echo server that can also respond to interactive commands that the user types to standard input. In this case, the server must respond to two independent I/O events: (1) a network client making a connection request, and (2) a user typing a command line at the keyboard. Which event do we wait for first? Neither option is ideal.

      One solution to this dilemma is a technique called I/O multiplexing. The basic idea is to use the select function to ask the kernel to suspend the process, returning control to the application only after one or more I/O events have occurred. The code below shows how we might use select to implement an iterative echo server that also accepts user commands on the standard input.

int main(int argc, char **argv)
 {
		 if (argc != 2) {
				 fprintf(stderr, "usage: %s <port>\n", argv[0]);
				 exit(0);
		 }
		 int port = atoi(argv[1]);
		 socklen_t clientlen = sizeof(struct sockaddr_in);
		 struct sockaddr_in clientaddr;		 
		 int listenfd = open_listenfd(port);
		 
		 fd_set read_set, ready_set; 
		 FD_ZERO(&read_set);			    // Clear read set
		 FD_SET(STDIN_FILENO, &read_set);	// Add stdin to read set
		 FD_SET(listenfd, &read_set);		// Add listenfd to read set
		 while (1) {				 
		 	   ready_set = read_set;
		 	   select(listenfd+1, &ready_set, NULL, NULL, NULL);
		 	   if (FD_ISSET(STDIN_FILENO, &ready_set))
		 	       command();			// Read command line from stdin
		 	   if (FD_ISSET(listenfd, &ready_set)) {
		 	       int connfd = accept(listenfd, (SA *) &clientaddr, &clientlen);
		 	       echo(connfd);	    // Echo client input until EOF
		 	       close(connfd);
		 	   }
		 }
 }
We call the select  function, which blocks until either the listening descriptor or standard input is ready for reading. Once select returns, we use the FD_ISSET macro to determine which descriptors are ready for reading. For example, if the user hit the enter key, thus causing the standard input descriptor to become ready for reading.

      One advantage of event-driven programming based on I/O multiplexing is that event-driven designs give programmers more control over the behavior of their programs than process-based designs. Another advantage is that an event-driven server based on I/O multiplexing runs in the context of a single process, and thus every logical flow has access to the entire address space of the process. This makes it easy to share data between flows. A related advantage of running as single process is that you can debug your concurrent server as you would any sequential program, using a familiar debugging tool such as GDB. Finally, event-driven designs are often significantly more efficient than process-based designs because they do not require a process context switch to schedule a new flow.

      A significant disadvantage of event-driven designs is coding complexity. Our event-driven concurrent echo server requires three times more code than the process-based server. Another significant disadvantage of event-based designs is that they cannot fully utilize multi-core processors.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值