select

本文介绍了用于管理套接字I/O行为的Select模型。通过一个LINUX程序设计实例详细展示了Select模型的工作原理及其应用过程,帮助读者理解如何使用Select模型来处理多连接情况下的输入输出操作。

套接字模式:阻塞套接字和非阻塞套接字。或者叫同步套接字和异步套接字。
套接字模型:描述如何对套接字的I/O行为进行管理。

一、 select模型的产生

先看一下下面的这句代码:
int iResult = recv(s, buffer,1024);
这是用来接收数据的,在默认的阻塞模式下的套接字里,recv会阻塞在那里,直到套接字连接上有数据可读,把数据读到buffer里后recv函数才会返回,不然就会一直阻塞在那里。在单线程的程序里出现这种情况会导致主线程(单线程程序里只有一个默认的主线程)被阻塞,这样整个程序被锁死在这里,如果永远没数据发送过来,那么程序就会被永远锁死。这个问题可以用多线程解决,但是在有多个套接字连接的情况下,这不是一个好的选择,扩展性很差。Select模型就是为了解决这个问题而出现的。

二、select模型简介

select返回fd_set中可用的套接字个数。 

fd_set是一个SOCKET队列,以下宏可以对该队列进行操作:

FD_CLR( s, *set) 从队列set删除句柄s;

FD_ISSET( s, *set) 检查句柄s是否存在与队列set中;

FD_SET( s, *set )把句柄s添加到队列set中;

FD_ZERO( *set ) 把set队列初始化成空队列.


三、LINUX 程序设计 select实例


/*  For our final example, server5.c, 
    we include the sys/time.h and sys/ioctl.h headers in place of signal.h
    in our last program and declare some extra variables to deal with select.  */


#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;
    int result;
    fd_set readfds, testfds;


/*  Create and name a socket for the server.  */


    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);


    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    server_address.sin_port = htons(9734);
    server_len = sizeof(server_address);


    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);


/*  Create a connection queue and initialize readfds to handle input from server_sockfd.  */


    listen(server_sockfd, 5);


    FD_ZERO(&readfds);
    FD_SET(server_sockfd, &readfds);


/*  Now wait for clients and requests.
    Since we have passed a null pointer as the timeout parameter, no timeout will occur.
    The program will exit and report an error if select returns a value of less than 1.  */


    while(1) {
        char ch; 
        int fd; 
        int nread;


        testfds = readfds;


        printf("server waiting...\n");
        result = select(FD_SETSIZE, &testfds, (fd_set *)0, 
            (fd_set *)0, (struct timeval *) 0); 


        printf("FD_SETSIZE = %d \n", FD_SETSIZE);
        if(result < 1) {
            perror("server5");
            exit(1);
        }   


/*  Once we know we've got activity,
    we find which descriptor it's on by checking each in turn using FD_ISSET.  */
        printf("hello\n");
        printf("FD_SETSIZE = %d \n", FD_SETSIZE);
        for(fd = 0; fd < FD_SETSIZE; fd++) {
                if(FD_ISSET(fd,&testfds)) {


/*  If the activity is on server_sockfd, it must be a request for a new connection
    and we add the associated client_sockfd to the descriptor set.  */


                if(fd == server_sockfd) {
                    client_len = sizeof(client_address);
                    client_sockfd = accept(server_sockfd,
                        (struct sockaddr *)&client_address, &client_len);
                    FD_SET(client_sockfd, &readfds);
                    printf("adding client on fd %d\n", client_sockfd);
                }


/*  If it isn't the server, it must be client activity.
    If close is received, the client has gone away and we remove it from the descriptor set.
    Otherwise, we 'serve' the client as in the previous examples.  */


                else {
                    ioctl(fd, FIONREAD, &nread);


                    if(nread == 0) {
                        close(fd);
                        FD_CLR(fd, &readfds);
                        printf("removing client on fd %d\n", fd);
                    }


                    else {
                        read(fd, &ch, 1);
                        printf("serving client on fd %d\n", fd);
                    //    sleep(5);
                        ch++;
                        write(fd, &ch, 1);
                    }
                }
            }
        }
    }
}


内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问题上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问题,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值