select多路复用

1.在socket的使用中我们经常用多路复用的方式来避免使用while的循环查询监听,至于如何使用详细的请看man 2 select

int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);


nfds:被监听的描述符

readfs:可读描述符集

writedfs:可写描述符集

timeout:堵塞时间

 

 

例子:

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>

void display_time(const char *str)
{
	int seconds;
	seconds = time((time_t*)NULL);
	printf("%s,%d\n",str,seconds);
}

int main(void)
{
	fd_set readfds;
	struct timeval timeout;
	int ret;
	FD_ZERO(&readfds);
	FD_SET(0,&readfds);

	timeout.tv_sec = 10;
	timeout.tv_usec = 0;
	while(1)
	{
		display_time("before select");
		ret = select(1,&readfds,NULL,NULL,&timeout);

		switch(ret){
			case 0:
				printf("NO DATA IN TEN SECONDS.\n");exit(0);break;
			case -1:
				perror("SELECT");
				exit(1);break;
			default:
				getchar();
				printf("Data is avilable now.\n");
		}
	}
	return 0;

}

重要的是时间的设置,这里我们使用10秒堵塞的时间,在十秒内如果描述符readfds有可读的加入就立即返回,否则一直等待知道10秒后返回0

 

不过有趣的是我在反汇编看到

	.file	"select.c"
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"%s,%d\n"
	.text
.globl display_time
	.type	display_time, @function
display_time:
.LFB33:
	.cfi_startproc
	pushq	%rbx
	.cfi_def_cfa_offset 16
	movq	%rdi, %rbx
	.cfi_offset 3, -16
	movl	$0, %edi
	call	time
	movl	%eax, %ecx
	movq	%rbx, %rdx
	movl	$.LC0, %esi
	movl	$1, %edi
	movl	$0, %eax
	call	__printf_chk
	popq	%rbx
	ret
	.cfi_endproc
.LFE33:
	.size	display_time, .-display_time
	.section	.rodata.str1.1
.LC1:
	.string	"before select"
.LC2:
	.string	"NO DATA IN TEN SECONDS.\n"
.LC3:
	.string	"SELECT"
.LC4:
	.string	"Data is avilable now.\n"
	.text
.globl main
	.type	main, @function
main:
.LFB34:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%rbx
	.cfi_def_cfa_offset 24
	subq	$152, %rsp
	.cfi_def_cfa_offset 176
	movq	%rsp, %rdi
	movl	$16, %ecx
	movl	$0, %eax
#APP
# 18 "select.c" 1
	cld; rep; stosq
# 0 "" 2
#NO_APP
	orq	$1, (%rsp)
	movq	$10, 128(%rsp)
	movq	$0, 136(%rsp)
	leaq	128(%rsp), %rbx
	.cfi_offset 3, -24
	.cfi_offset 6, -16
.L7:
	movl	$.LC1, %edi
	call	display_time
	movq	%rbx, %r8
	movl	$0, %ecx
	movl	$0, %edx
	movq	%rsp, %rsi
	movl	$1, %edi
	call	select
	cmpl	$-1, %eax
	je	.L5
	testl	%eax, %eax//这里不是一直为正确的状态么?(意味着.L9的跳转是必然)
	jne	.L9
	movl	$.LC2, %esi
	movl	$1, %edi
	call	__printf_chk
	movl	$0, %edi
	call	exit
.L5:
	movl	$.LC3, %edi
	call	perror
	movl	$1, %edi
	call	exit
.L9:
	movq	stdin(%rip), %rdi
	call	_IO_getc
	movl	$.LC4, %esi
	movl	$1, %edi
	movl	$0, %eax
	call	__printf_chk
	jmp	.L7
	.cfi_endproc
.LFE34:
	.size	main, .-main
	.ident	"GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5.1) 4.4.5"
	.section	.note.GNU-stack,"",@progbits


 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值