网站开发找哪个,怎么验证网站备案密码是否正确,网站建设销售技巧话术,2021百度新算法优化前言最近在写一个小程序#xff0c;也就是简单的系统调用#xff0c;但是神奇的是#xff0c;我用的这个系统调用刚好就阻塞了。如果你也写过应用程序#xff0c;肯定也会遇到过这样的问题。后来#xff0c;发现了select这个好东西#xff0c;可以用来监听文件描述。sele… 前言最近在写一个小程序也就是简单的系统调用但是神奇的是我用的这个系统调用刚好就阻塞了。如果你也写过应用程序肯定也会遇到过这样的问题。后来发现了select这个好东西可以用来监听文件描述。select的作用如果我们在read一个文件如果文件马上有东西返回那是非常愉快的事情但是经常遇到一些情况read不能马上返回数据这时候会造成我们的线程阻塞就卡在那里不动。如果是ui界面那情况就显得很尴尬你的ui卡主了作为一个计算机用户那是一件非常崩溃的事情的。人们为了解决这个问题select就出现了。select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become ready for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.select 和 pselect 允许程序监听文件描述符文件描述符是打开文件的时候返回从一个整数这个整数代表了一个文件大家都叫他做文件描述符。直到文件描述符准备好了IO操作。原来的代码#include sys/stat.h
#include fcntl.h
#include unistd.h
#include stdio.h
#include stdlib.h
#include string.h
#include linux/ioctl.h
#include unistd.h
#include sys/time.h
#include sys/types.h#define RETRY_TIMES (20)
#define COM_STR ezsp verint main(int argc, char * const argv[])
{int fd_in,fd_out,size;int retry_times0;int ret0;//char s[ ]info\n,buffer[1024];char s[ ]version\n,buffer[1024];printf( weiqifa Zigbee test start ...\n);printf(argc:%d\n,argc);printf(argv[0]:%s\n,argv[0]);/*打开写管道文件*/fd_inopen(/dev/gateway_in,O_RDWR);if(fd_in0){printf(weiqifa open error:%d\n,fd_in);return(0);}/*打开读管道文件*/fd_outopen(/dev/gateway_out,O_RDWR);if(fd_out0){printf(weiqifa open error:%d\n,fd_out);return(0);}/*循环读写*/do{ret write(fd_in,s,sizeof(s));size read(fd_out,buffer,sizeof(buffer));printf(%s,buffer);if(strncmp(COM_STR,buffer,strlen(COM_STR) -1) 0){break;}usleep(3000);}while(retry_times RETRY_TIMES);if(retry_times RETRY_TIMES){printf(\nfail\n);return (-1);}/*关闭管道*/close(fd_out);close(fd_in);printf(\nsuccess\n);return (0);
}
修改后的代码#include sys/stat.h
#include fcntl.h
#include unistd.h
#include stdio.h
#include stdlib.h
#include string.h
#include linux/ioctl.h
#include unistd.h
#include sys/time.h
#include sys/types.h#define RETRY_TIMES (20)
#define COM_STR ezsp verint main(int argc, char * const argv[])
{int fd_in,fd_out,size;int retry_times0;int ret0;struct timeval tv;fd_set rdfds;/*清空rdfds*/FD_ZERO(rdfds);//char s[ ]info\n,buffer[1024];char s[ ]version\n,buffer[1024];printf( weiqifa Zigbee test start ...\n);printf(argc:%d\n,argc);printf(argv[0]:%s\n,argv[0]);/*打开写管道文件*/fd_inopen(/dev/gateway_in,O_RDWR);if(fd_in0){printf(weiqifa open error:%d\n,fd_in);return(0);}/*打开读管道文件*/fd_outopen(/dev/gateway_out,O_RDWR);if(fd_out0){printf(weiqifa open error:%d\n,fd_out);return(0);}/*循环读写*/do{ret write(fd_in,s,sizeof(s));tv.tv_sec 1; /*秒*/tv.tv_usec 500; /*微秒*//*添加监听的设备描述符*/FD_ZERO(rdfds);FD_SET(fd_out,rdfds);/*监听fd_out*/ret select(fd_out1,rdfds,NULL,NULL,tv);if(ret0){printf(selcet error\r\n);retry_times RETRY_TIMES;break;}else if(ret 0){ /*超时*/printf(timeout \r\n);retry_times RETRY_TIMES;break;}else{printf(ret %d \r\n,ret);}size read(fd_out,buffer,sizeof(buffer));printf(%s,buffer);if(strncmp(COM_STR,buffer,strlen(COM_STR) -1) 0){break;}usleep(3000);}while(retry_times RETRY_TIMES);if(retry_times RETRY_TIMES){printf(\nfail\n);return (-1);}/*关闭管道*/close(fd_out);close(fd_in);printf(\nsuccess\n);return (0);
}
select代码的小例子 #include stdio.h#include stdlib.h#include sys/select.hintmain(void){fd_set rfds;struct timeval tv;int retval;/* Watch stdin (fd 0) to see when it has input. */FD_ZERO(rfds);FD_SET(0, rfds);/* Wait up to five seconds. */tv.tv_sec 5;tv.tv_usec 0;retval select(1, rfds, NULL, NULL, tv);/* Dont rely on the value of tv now! */if (retval -1)perror(select());else if (retval)printf(Data is available now.\n);/* FD_ISSET(0, rfds) will be true. */elseprintf(No data within five seconds.\n);exit(EXIT_SUCCESS);}
执行 第一次执行的时候我没有输入任何内容这时候select就一直监听标准输入因为没有输入就一直等等到了超时时间程序就退出了。第二次执行的时候我给标准输入输入东西了select马上就返回并打印了数据是有效的。深入理解select模型理解select模型的关键在于理解fd_set,为说明方便取fd_set长度为1字节fd_set中的每一bit可以对应一个文件描述符fd。则1字节长的fd_set最大可以对应8个fd。执行fd_set set; FD_ZERO(set); 则set用位表示是0000,0000。若fd5,执行FD_SET(fd,set);后set变为0001,0000(第5位置为1)若再加入fd2fd1,则set变为0001,0011执行select(6,set,0,0,0)阻塞等待若fd1,fd2上都发生可读事件则select返回此时set变为0000,0011。注意没有事件发生的fd5被清空。最后举个例子#include sys/stat.h
#include fcntl.h
#include unistd.h
#include stdio.h
#include stdlib.h
#include string.h
#include linux/ioctl.h
#include unistd.h
#include sys/time.h
#include sys/types.hint main(int argc, char * const argv[])
{int fd_out,size;int ret0;struct timeval tv;fd_set rdfds;char buffer[1024];printf( weiqifa test start ...\n);printf(argc:%d\n,argc);printf(argv[0]:%s\n,argv[0]);/*打开读管道文件*/fd_outopen(./test,O_RDWR);if(fd_out0){printf(weiqifa open error:%d\n,fd_out);return(0);}/*清空rdfds*/FD_ZERO(rdfds);/*添加监听的设备描述符*/FD_SET(fd_out,rdfds);tv.tv_sec 10; /*秒*/tv.tv_usec 500; /*微秒*//*监听fd_out*/ret select(fd_out1,rdfds,NULL,NULL,tv);if(ret0){printf(selcet error\r\n);goto exit;}else if(ret 0){ /*超时*/printf(timeout1 \r\n);goto exit;}else{printf(ret %d \r\n,ret);}size read(fd_out,buffer,sizeof(buffer));printf(%s,buffer);exit:/*关闭管道*/close(fd_out);printf(\nsuccess\n);return (0);
}
执行截图 PS想加入技术群的同学加了我好友后就给我发「篮球的大肚子」这句话有可能机器人打瞌睡可以多发几次不要发与技术无关的消息或者推广。如果想获取学习资料就在公众号后台回复「1024」足够多的学习资料可以让你学习。