掌桥专利:专业的专利平台
掌桥专利
首页

阻塞式异步监听多客户指令并控制多硬件的服务端架构、通信系统及方法

文献发布时间:2024-04-18 19:58:26


阻塞式异步监听多客户指令并控制多硬件的服务端架构、通信系统及方法

技术领域

本发明涉及通信技术领域,尤其涉及阻塞式异步监听多客户指令并控制多硬件的服务端架构、通信系统及方法。

背景技术

在航空电子、5G射频等通信领域,存在大量需要通过C/S体系网络并发控制一个或多个硬件设备的通信需求,其中客户一般使用上位机界面的客户端程序发出控制指令,然后通过搭载服务端程序的服务端设备解析指令并通过使用驱动文件描述符控制具体的受控硬件设备。

传统的多路IO复用服务端架构,在接收到多客户请求时,通常为每个客户分配单独的进程来处理,这种处理方式理论上操作简单,但是实际中的设备资源开销很大,而作为通信服务端使用的嵌入式主控设备内存资源非常紧张,对于运行的服务端程序有着严苛的轻量级要求。中国专利公开号CN113553199A,公开日为2021年10月26日,名称为“一种使用异步非阻塞模式处理多客户端接入的方法及装置”公开了一种处理多客户端接入的方法,包括主用工作组主用线程及线程池模块、辅助工作组工作线程及线程池模块、多路服务器和负载均衡模块,通过使用异步非阻塞模式,能够在一定程度上解决多客户端同时接入请求,然而此专利使用的是非阻塞式设计,在无客户请求时线程不能进入完全休眠的状态,会持续占用处理器和系统内存资源。

发明内容

本发明克服了现有的多客户通信服务端架构不够轻量级,在无客户连接请求和客户指令时持续占用内存和处理器资源等问题,提供了阻塞式异步监听多客户指令并控制多硬件的服务端架构、通信系统及方法,其中服务端架构采用异步阻塞式监听及接收客户指令的架构设计,通过创建使用无名管道和全局结构数组的方式,此架构所有线程空闲时均处于阻塞态,让出所占用的内存和处理器资源,并且在接收到客户请求时能快速唤醒接收客户指令,并通过硬件控制模块可并发地执行指令,所有线程共用一个进程就能实现多客户同时接入控制硬件设备的功能,该架构能同时满足嵌入式通信系统对多客户服务端架构轻量级、内存资源开销少、请求响应速度快、及时释放处理器资源等方面的需求。

为了实现上述目的,本发明采用以下方案:

阻塞式异步监听多客户指令并控制多硬件的服务端架构,包括网络交互模块和硬件控制模块,其中:

所述网络交互模块包括:

全局结构数组,其元素结构成员包括已连接客户的套接字和客户信息,所述套接字为阻塞套接字;

无名管道,其包括读端口和写端口;

客户连接监听线程,创建阻塞监听套接字sock,然后调用accept(sock, ...)阻塞监听新客户的连接请求,在无新客户连接时阻塞等待,在有新客户请求连接时被唤醒并返回新客户的套接字,保存已连接客户的套接字和客户信息到全局结构数组中,并向无名管道的写端口写入任意数据使其读端口转换为可读状态,然后再次调用accept函数继续阻塞监听等待其它客户的连接请求;

客户指令解析线程,其定义一个fd_set类型的空文件集fdSet,把无名管道的读端口和全局结构数组中的所有套接字依次加入文件集fdSet中,然后调用函数select监视文件集fdSet中是否有文件更新为可读状态,客户指令解析线程在未接收到客户连接请求或客户指令时阻塞于函数select调用处,出现以下情况时被唤醒并执行操作:

因出现系统异常情况被唤醒,根据异常返回值和实际异常情况进行对应的异常处理;

因无名管道读端口或客户的套接字变为可读状态被唤醒,函数select对文件集fdSet中的文件进行筛选并只保留其中的可读文件,先确认无名管道的读端口是否仍在文件集fdSet中,若是则清空无名管道的读端口使其恢复不可读状态,否则逐个确认全局结构数组中各客户套接字是否仍在文件集fdSet中,读取仍在文件集fdSet中的套接字接收的指令内容并解析后进行缓存,解析指令的结果包括指令指定的受控设备及控制方式;随后清空文件集fdSet并将无名管道的读端口和全局结构数组中的所有套接字重新加入文件集fdSet中,然后再次调用函数select对文件集fdSet进行下一轮监视以等待其中出现新的可读文件;

所述硬件控制模块包括:

并发指令队列和顺序指令队列,均用于对解析完成的指令进行分类缓存,若指令涉及对临界资源的访问则缓存至所述顺序指令队列,否则缓存至所述并发指令队列;

并发执行线程,其按先进先出的方式读取所述并发指令队列中的指令,并通过调用对应受控硬件驱动接口并发控制受控硬件;

顺序执行线程,其按先进先出的方式读取所述顺序指令队列中的指令,通过调用对应受控硬件驱动接口顺序控制受控硬件,顺序指令队列中每条指令的执行均等待上一条指令执行结束后开始;

所述客户连接监听线程、客户指令解析线程、并发执行线程和顺序执行线程各线程隶属于同一进程且异步并发运行。

作为优选,所述客户连接监听线程、客户指令解析线程、并发执行线程和顺序执行线程的线程属性均设置为PTHREAD_CANCEL_ASYNCHRONOUS,其中任一线程运行出错时调用函数pthread_cancel和pthread_join中止其它所有线程的运行并回收线程资源。

作为优选,所述网络交互模块对系统的SIGPIPE、SIGQUIT、SIGINT信号提前进行屏蔽。

作为优选,所述客户指令解析线程读取客户指令使用函数read、recv或recvfrom,并将缓冲区容量作为读取长度参数传入函数中,对客户套接字的写入使用函数write、send或sendto;若调用读写函数的返回值小于等于0,则跳过对此客户的读写并关闭此套接字,然后从全局结构数组中找到并清空该客户对应的元素结构信息,然后继续监视和处理其它客户的套接字。

作为优选,架构包括对全局结构数组中客户套接字的读写保护机制,其采用与各套接字一一对应的文件锁,将客户套接字的读写操作放在lockf(socket, F_LOCK, 0)和lockf(socket, F_UNLOCK, 0)之间形成的临界区,其中socket为被保护的套接字。

作为优选,所述网络交互模块创建有用于指示已连接客户数量的信号量sem_connectClt,所述信号量sem_connectClt初值为0,在监听到一个新客户连接请求并建立连接后对信号量sem_connectClt进行一次V操作,在接收到一个已连接客户的退出指令后对信号量sem_connectClt进行一次P操作并关闭该客户套接字以及清空全局结构数组中的该客户的元素结构成员信息,所述客户指令解析线程在读取完所有客户指令后对信号量sem_connectClt进行一次P操作,当信号量sem_connectClt的值小于0时客户指令解析线程进入阻塞状态,线程被唤醒后对信号量sem_connectClt先额外进行一次V操作。

作为优选,所述的阻塞式异步监听多客户指令并控制多硬件的服务端架构,其特征在于,将对全局结构数组的元素的读取或修改操作均在信号量或互斥锁所形成的临界区中完成。

作为优选,所述硬件控制模块还创建有初值均为0的信号量b和信号量s,所述信号量b和信号量s分别用于指示当前并发指令队列和顺序指令队列中的指令数,客户指令解析线程每往并发指令队列缓存一条解析完成的指令后对信号量b进行一次V操作,每往顺序指令队列缓存一条解析完成的指令后对信号量s进行一次V操作,并发执行线程每从并发指令队列中读取一条指令前对信号量b进行一次P操作,顺序执行线程每从顺序指令队列中读取一条指令前对信号量s进行一次P操作。

本申请还提供阻塞式异步监听多客户指令并控制多硬件的通信系统,包括:

用户上位机,其包括多个具有网络通信功能的客户端设备,通过网络发送用户指令;

受控硬件,其提供硬件驱动接口和驱动模块,用于完成对应的硬件操作;

嵌入式主控网络设备,其架构设计采用以上方案或优选方案中任一项所提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构,所述嵌入式主控网络设备运行有服务端程序,与所述受控硬件连接并加载有所述驱动模块,所述服务端程序用于接收和解析所述用户上位机发出的指令得到硬件控制信息,并根据硬件控制信息调用对应硬件驱动接口和驱动模块使受控硬件完成对应的硬件操作。

本申请还提供阻塞式异步监听多客户指令并控制多硬件的方法,基于以上方案或优选方案中任一项所提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构,方法包括以下步骤:

S1:定义用于保存客户信息和已连接客户的阻塞套接字的全局结构数组,客户连接监听线程创建阻塞监听套接字sock;客户指令解析线程创建fd_set类型的文件集fdSet,创建无名管道,所述无名管道包括读端口pipe[0]和写端口pipe[1];

S2:客户连接监听线程调用函数accept阻塞等待新客户的连接请求;客户指令解析线程统计全局结构数组中的套接字和pipe[0]一起加入文件集fdSet中,然后调用函数select阻塞等待文件集fdSet中更新可读文件;并发执行线程和顺序执行线程分别阻塞等待并发指令队列和顺序指令队列中存入指令;

S3:接收到新客户的连接请求时,客户连接监听线程被唤醒,将accept函数返回的新客户的套接字和客户信息更新到全局结构数组中,并向无名管道的写端口pipe[1]写入任意字符使文件集fdSet中的无名管道读端口pipe[0]变为可读状态;接收到已连接的客户通过套接字发送的指令时对应套接字变为可读状态;

S4:客户指令解析线程被唤醒,函数select从文件集fdSet中筛选并只保留其中的可读文件,确认无名管道读端口pipe[0]是否仍在被筛选后的可读文件集fdSet中,若是则清空无名管道的读端口pipe[0]并返回到步骤S2,否则逐个确认全局结构数组中的各客户套接字是否在可读文件集fdSet中,并读取和解析仍在可读文件集fdSet中的套接字的指令内容,将不涉及临界资源的指令缓存至并发指令队列,唤醒并发执行线程读取并执行并发指令队列中的指令,将涉及临界资源的指令缓存至顺序指令队列,唤醒顺序执行线程读取并执行顺序指令队列中的指令;当所有指令均已缓存至指令队列时返回步骤S2。

本发明至少包括以下有益效果:(1)采用单进程的结构设计,不占用过多内存资源,足够轻量级;(2)所有线程在空闲时均处于阻塞态,不持续占用CPU,以提高通信系统和通信设备的整体运行效率;(3)区分了客户指令是否涉及临界资源的访问,通过设置顺序指令队列或和并发指令队列,既避免了对同一临界硬件资源的同时访问产生的竞态问题,又保证了指令执行的顺序与接收顺序一致;(4)各线程和任务的运行、阻塞、或中止均是异步并发的,既不会互相干扰,出错时也能顺利回收处于阻塞态的线程资源;(5)通过设置文件锁,保证了轻量级和代码可重入性的同时,实现了对同一个客户套接字的访问互斥;(6)在实现在监听多客户指令的同时,可完成对多个硬件设备的灵活控制,对嵌入式通信有很强的适配性。

附图说明

图1为本申请提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构示意图;

图2为本申请提供的阻塞式异步监听多客户指令并控制多硬件的通信系统示意图;

图3为本申请提供的阻塞式异步监听多客户指令并控制多硬件的方法流程图。

具体实施方式

下面结合附图对本发明做进一步的详细说明,以令本领域技术人员参照说明书文字能够据以实施。

如图1所示,阻塞式异步监听多客户指令并控制多硬件的服务端架构,包括网络交互模块和硬件控制模块,其中:

网络交互模块包括:

全局结构数组,其元素结构成员包括已连接客户的套接字和客户信息,其中套接字为阻塞套接字;全局结构数组中的信息由整个进程中的所有线程共用,其中的每个元素结构成员记录一个已连接客户的套接字和该客户的基本信息,记录的客户套接字为阻塞套接字,使用阻塞套接字可以使服务端与客户的连接关系符合阻塞的条件,保证在没有收到客户请求和客户指令时,线程可以在调用select监视客户套接字的位置正常进入阻塞休眠的状态,在有新客户连接时全局结构数组中对应增加元素结构成员以记录该客户的信息,当有客户断开连接时将其对应的元素结构成员信息删除,以保证全局结构数组中的信息与已连接客户的信息实时同步,在服务端实际运行中,对于全局结构数组的访问修改是互斥的,可以保证代码的可重入性。

无名管道,其包括读端口和写端口;无名管道是类Unix系统的特殊文件,由pipe()函数创建,包括固定的两个端口,其中pipe[0]为读端口,pipe[1]为写端口,通过在写端口写入数据可以使对应读端口变为可读状态,在写端口写入的数据可以在读端口按写入顺序读取出来,无名管道只需占用极少的内存资源,并且可以随着进程结束而释放空间。

客户连接监听线程,其创建阻塞监听套接字sock,然后调用accept(sock, ...)阻塞监听新客户的连接请求,在无新客户连接时阻塞等待,在有新客户请求连接时被唤醒并返回新客户的套接字,保存已连接客户的套接字和客户信息到全局结构数组中,并向无名管道的写端口写入任意数据使其读端口转换为可读状态,然后再次调用accept函数继续阻塞监听等待其它客户的连接请求;accept函数在未检测到新客户连接请求时会进入阻塞状态,使整个客户连接监听线程进入阻塞状态被系统挂起而让出占用的内存和计算资源,直到下次接收到新客户连接请求后accept函数恢复运行,客户连接监听线程被唤醒以处理新客户的连接请求,在将新客户的套接字和客户信息更新到全局结构数组中的同时,会向无名管道的写端口写入任意数据,写入的数据主要起到使读端口进入可读状态的作用,数据内容可以无实际意义。

客户指令解析线程,其定义一个fd_set类型的空文件集fdSet,把无名管道的读端口和全局结构数组中的所有套接字依次加入文件集fdSet中,然后调用函数select监视文件集fdSet中是否有文件更新为可读状态,客户指令解析线程在未接收到客户连接请求或客户指令时阻塞于函数select调用处,出现以下情况时被唤醒并执行操作:

因出现系统异常情况被唤醒,根据异常返回值和实际异常情况进行对应的异常处理;系统异常情况通常包括客户端异常关闭、被信号打断、事件发生等,当出现系统异常时会返回对应的异常返回值,这时候根据异常返回值获取实际异常情况信息,并根据系统日志进行相应的异常处理操作,使系统恢复到正常运行状态。

因无名管道读端口或客户的套接字变为可读状态被唤醒,函数select对文件集fdSet中的文件进行筛选并只保留其中的可读文件,先确认无名管道的读端口是否仍在文件集fdSet中,若是则清空无名管道的读端口使其恢复不可读状态,否则逐个确认全局结构数组中各客户套接字是否仍在文件集fdSet中,读取仍在文件集fdSet中的套接字接收的指令内容并解析后进行缓存,解析指令的结果包括指令指定的受控设备及控制方式;随后清空文件集fdSet并将无名管道的读端口和全局结构数组中的所有套接字重新加入文件集fdSet中,然后再次调用函数select对文件集fdSet进行下一轮监视以等待其中出现新的可读文件。

客户指令解析线程通过调用函数select查询文件集fdSet中的信息,函数select继续向下运行的条件为文件集fdSet中出现可读文件,即其中的套接字或无名管道的读端口至少有一个变为可读状态,否则整个客户指令解析线程都随函数select的阻塞而阻塞,函数select的调用方式为select(maxfd+1,&fdSet, NULL, NULL, NULL),其中maxfd为文件集fdSet中的最大文件描述符。

当无名管道的读端口为可读时,表示客户连接监听线程接收到了新客户的连接请求并向无名端口的写端口写入了数据,此时新客户的套接字及客户信息被记录到全局结构数组中,清空无名管道的读端口以正常等待下一次新客户连接请求,然后将全局结构数组中的客户套接字全部更新到文件集fdSet中,此时新客户的身份转变为已连接客户,其发送的指令可以被正常接收,完成以上操作后重新调用函数select,若查询到有可读套接字则正常读取客户指令,因为新客户请求连接后不一定紧接着发送指令,所以可能无可读套接字从而线程再次进入阻塞状态。

当有套接字的状态为可读时,客户指令解析线程调用FD_ISSET( ct[i].S,&fdSet) 依次筛选可读套接字并读取对应的客户指令,直到接收完所有客户指令,对接收到的客户指令进行解析,根据需要控制的硬件设备对客户指令进行分类,其中不涉及临界资源访问指令缓存至硬件控制模块的并发指令队列,将涉及临界资源访问的指令缓存至硬件控制模块的顺序指令队列,临界资源为不可被两个或以上线程同时访问的硬件资源,通过互斥访问的机制保证涉及操作这些临界资源的客户指令不会因为资源冲突而产生异常。然后网络交互模块的客户连接监听线程继续阻塞监听等待新客户连接,网络交互模块的客户指令解析线程继续调用函数select阻塞监视可读套接字,指令的执行交给硬件控制模块进行。客户指令解析线程在接收读取客户指令时,会传入暂存客户指令的缓冲区的最大长度,保证一次性读出筛选出的可读套接字中的所有数据且解析过程中不再进行二次存储搬运,通过接收读取函数的返回值可判断客户端是否异常关闭或读取被中断信号打断。与客户端交互的指令采用的协议帧在帧头给出负载长度,从而能快速识别每条指令内容在缓冲区的存放起点、终点位置,在流量爆发时能迅速判断出是否没有一次读取到指令帧的全部分片,从而先读取筛选出的其它客户数据后再回来进行二次读取组合解析指令,保证多客户响应的公平性与实时性。

硬件控制模块包括:

并发指令队列和顺序指令队列,均用于对解析完成的指令进行分类存放,若指令不涉及对临界资源的访问则存入并发指令队列,否则存入顺序指令队列;指令由客户指令解析线程接收和解析,之后系统根据指令需要用到的资源是否涉及临界资源判断是缓存至并发指令队列或是顺序指令队列中,并发指令队列和顺序指令队列均被创建为先进先出的读写方式,在读取和执行其中的指令时,两者存在差异,并发指令队列中可以按顺序一次读取多条指令并执行,而顺序指令队列中只有在执行完当前指令后才能读取和执行下一条指令。

并发执行线程,其按先进先出的方式读取并发指令队列中的指令,并通过调用对应硬件驱动接口并发控制对应的受控设备;并发指令队列中的客户指令均不涉及临界资源,所以可以并发执行,各指令独立快速执行,可以极大地提高执行效率,根据并发执行线程的指令处理能力将最先放入并发指令队列的一部分指令读取并执行,当有指令执行完成时按先进先出的原则继续读取指令来执行,使同时执行的指令维持在一定数量直到清空并行指令队列,使用的硬件驱动文件描述符由系统配置,可以通过描述符直接控制硬件设备,其中一部分客户指令使用的描述符包含在客户信息中,不需要去系统配置文件中调用。

顺序执行线程,其按先进先出的方式读取顺序指令队列中的指令,并通过调用对应硬件驱动接口顺序控制对应的受控设备。顺序指令队列中的客户指令至少涉及一项临界资源的使用,如果下一条客户指令需要用到的临界资源正在被当前执行的指令访问,则必须要等到当前指令释放处临界资源后才能执行下一条客户指令,所以顺序执行线程按照先进先出的原则逐条执行顺序指令队列里的指令,保证客户指令执行的公平性。

所述客户连接监听线程、客户指令解析线程、并发执行线程和顺序执行线程各线程隶属于同一进程且异步并发运行。各线程异步并发运行且相互独立,客户指令解析线程对客户指令的读取和解析无需等待并发执行线程或顺序执行线程执行完队列中缓存的指令,具有极高的运行效率。

在采用该架构的服务端运行过程中,客户连接监听线程和客户指令解析线程空闲时都处于阻塞状态,如果接收到已连接客户的客户指令,客户指令解析线程会被直接唤醒,函数select继续向下运行,先确认无名管道读端口是否可读,若可读则重新统计全局结构数组ct[]中已连接客户套接字和无名管道读端口一起加入到文件集fdSet中再次调用函数select,此时若没有新客户发起连接请求且已连接的客户套接字接收到了客户指令,则再次从函数select调用处唤醒,筛选文件集fdSet中的可读套接字,接收读取并解析对应的客户指令,将客户指令发送给硬件控制模块,硬件控制模块根据各指令是否涉及临界资源分别使用并行执行线程和顺序执行线程来执行这些客户指令。由于文件集fdSet中没有预先存入新客户的套接字,新客户发送的连接请求和客户指令不能直接唤醒客户指令解析线程,此时若有已连接客户发送的指令唤醒了客户指令解析线程也能顺便接收到新客户的指令,为了避免因老客户无请求时客户指令解析线程阻塞而错过新连接客户的指令读取,向无名管道的写端口写入数据,检测到文件集fdSet中无名管道的读端口为可读状态,线程被及时唤醒将新客户的套接字更新到文件集fdSet中,再次调用函数select即可接收读取新客户的指令并继续执行后续操作。

此架构中客户连接监听线程和客户指令解析线程采用空闲时阻塞的设计,在无连接请求和客户指令时可以释放出占用的内存和计算资源以提高通信系统的整体运行效率,减少系统能耗。用全局结构数组存储客户套接字,通过无名管道唤醒客户指令解析线程,不会因为客户指令解析线程的阻塞而错过新客户的连接请求和发送的指令,可以快速作出响应。通过将客户指令分类并用并发执行线程和顺序执行线程分别执行,提高了指令执行效率。对于常见的应用场景,如已连接客户数量小于20且使用频率高于1Ghz的多核CPU,网络交互模块能在ns级的时间内完成一轮循环,包括对筛选出的所有可读客户的所有指令的按序读取解析,保障每个客户得到快速响应且察觉不到部分情况下可能出现的时分复用的存在。搭载服务端程序的设备会提前加载所有受控硬件的驱动模块以保证对硬件驱动接口函数的正常调用。整个架构采用单进程多线程的结构设计,多客户的连接监听、指令读取、指令执行均只需一个进程即可完成,足够轻量级,当然若是有超过单进程处理能力的大量指令请求,可以通过复制进程并进行负载均衡的方式来应对超高负载的情况。

在另一种技术方案中,客户连接监听线程、客户指令解析线程、并发执行线程和顺序执行线程的线程属性均设置为PTHREAD_CANCEL_ASYNCHRONOUS,其中任一线程运行出错时调用函数pthread_cancel和pthread_join中止其它所有线程的运行并回收线程资源。线程属性中包括有可取消类型属性,将这项属性设置为PTHREAD_CANCEL_ASYNCHRONOUS,这种状态下的线程可以随时退出运行而无需运行到取消点,在执行任务出错时可以调用pthread_cancel函数异步取消其它线程,避免了处于阻塞态的线程无法自己主动释放资源而成为僵尸线程的问题。

网络交互模块对系统的SIGPIPE、SIGQUIT、SIGINT信号提前进行屏蔽,避免因客户端异常关闭或用户错误操作导致服务端的线程在执行过程中被打断或在阻塞状态下被异常唤醒,例如异常中断产生时read或recv等IO操作被打断或函数select被异常唤醒。

在另一种技术方案中,客户指令解析线程读取客户指令使用函数read、recv或recvfrom,并将缓冲区容量作为读取长度参数传入函数中,对客户套接字的写入使用函数write、send或sendto;若调用读写函数的返回值小于等于0,则跳过对此客户的读写并关闭此套接字,然后从全局结构数组中找到并清空该客户对应的元素结构信息,然后继续监视和处理其它客户的套接字。使用read或recv或recvfrom函数,传入的读取长度参数为代码定义的缓冲区容量,当套接字内可读指令长度小于等于缓冲区容量时会一次性读出所有可读内容并返回实际读取长度值。若调用读写函数的返回值小于等于0,说明用户所在的客户端套接字被用户关闭或IO操作被异常打断,为确保系统正常运行,跳过对此客户读写并关闭此套接字。

该架构还包括对全局结构数组中客户套接字的读写保护机制,其采用与各套接字一一对应的文件锁,将客户套接字的读写操作放在lockf(socket, F_LOCK, 0)和lockf(socket, F_UNLOCK, 0)之间形成的临界区,其中socket为被保护的套接字。通过设置文件锁可以保证对同一客户套接字的IO操作互斥进行。

将对全局结构数组的元素的读取或修改操作均在信号量或互斥锁所形成的临界区中完成,以避免多个线程同时访问全局结构数组。

在另一种技术方案中,硬件控制模块还创建有初值均为0的信号量b和信号量s,所述信号量b和信号量s分别用于指示当前并发指令队列和顺序指令队列中的指令数,户指令解析线程每往并发指令队列缓存一条解析完成的指令后对信号量b进行一次V操作,每往顺序指令队列缓存一条解析完成的指令后对信号量s进行一次V操作,并发执行线程每从并发指令队列中读取一条指令前对信号量b进行一次P操作,顺序执行线程每从顺序指令队列中读取一条指令前对信号量s进行一次P操作。P操作和V操作是对信号量的常见操作,一次P操作会使对应信号量的值减少1,当信号量的值减少到小于0后线程将进入阻塞状态,一次V操作会使对应信号量的值增加1,当信号量的值大于等于0时线程将会继续运行,信号量b和信号量s用于指示对应指令队列所缓存的指令数量,当指令队列中的指令被全部执行完之后,信号量的值也由于P操作正好被减少到小于0,在服务端再次接收到新的客户指令之前,指令队列将保持为空,此时因为信号量的值小于0,对应的指令执行线程进入阻塞状态,在再次接收到客户指令后,指令队列转为非空状态,信号量的值由于V操作而不小于0,可以正常唤醒指令执行线程。

在另一种技术方案中,网络交互模块创建有用于指示已连接客户数量的信号量sem_connectClt,信号量sem_connectClt初值为0,在监听到一个新客户连接请求并建立连接后对信号量sem_connectClt进行一次V操作,在接收到一个已连接客户的退出指令后对信号量sem_connectClt进行一次P操作并关闭该客户套接字以及清空全局结构数组中的该客户的元素结构成员信息,客户指令解析线程在读取完所有客户指令后对信号量sem_connectClt进行一次P操作,当信号量sem_connectClt的值小于1时客户指令解析线程进入阻塞状态,线程被唤醒后对信号量sem_connectClt先额外进行一次V操作,避免无客户连接但无名管道被意外破坏导致线程无法在函数select调用处阻塞的情况。监听到新客户时进行V操作,客户端关闭时进行P操作,客户指令读取线程的每轮循环中先进行P操作保证没有客户连接时线程休眠让出时间片节省CPU调度,有客户连接时线程被唤醒后进行V操作以保证信号量sem_connectClt值始终与已连接客户端数量相同,从而在全局结构数组中的查找已连接客户时通过信号量值就可获知已连接客户总数量从而提高查找速度。

本申请还提供多客户可并发控制通信设备的通信系统,如图2所示,系统包括:

用户上位机,其包括多个具有网络通信功能的客户端设备,通过网络发送用户指令;

受控硬件,其提供硬件驱动接口和驱动模块,用于完成对应的硬件操作;

嵌入式主控网络设备,其架构设计采用以上任一项方案所提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构,嵌入式主控网络设备运行有服务端程序,与受控硬件连接并加载有驱动模块,服务端程序用于接收和解析用户上位机发出的指令得到硬件控制信息,并根据硬件控制信息调用对应硬件驱动接口和驱动模块使受控硬件完成对应的硬件操作。

客户端设备至少存在一个,可以是分别运行在多个不同上位机电脑的界面应用程序,也可以是运行在同一上位机的多个界面应用程序;本申请所设计的通信系统可以运行在搭载了类Unix操作系统的嵌入式主控网络设备中,通过网络接收来自客户端的控制指令,并将反馈信号返回给客户端;嵌入式主控设备在上电时会根据实际可能要控制的硬件设备,通过自启动脚本或手动插入的方式提前加载所有的对应驱动模块,在物理上通过IIC、SPI等总线实现对受控硬件的控制,在软件上通过打开硬件驱动文件描述符并进行相应的系统调用实现对应的硬件控制。

由于嵌入式主控网络设备采用了本申请提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构,此系统可以实现多个用户上位机同时通过嵌入式主控网络设备访问和控制受控硬件的功能,并且此系统具有轻量级、节省资源、响应快速等优点。

本申请还提供多客户可并发控制通信设备的方法,基于以上任一项方案所提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构,如图3所示,方法包括以下步骤:

S1:定义用于保存客户信息和已连接客户的阻塞套接字的全局结构数组,客户连接监听线程创建阻塞监听套接字sock;客户指令解析线程创建fd_set类型的空文件集fdSet,创建无名管道,无名管道包括读端口pipe[0]和写端口pipe[1];

S2:客户连接监听线程调用函数accept阻塞等待新客户的连接请求;客户指令解析线程统计全局结构数组中的套接字和pipe[0]一起加入空文件集fdSet中,然后调用函数select阻塞等待文件集fdSet中更新可读文件;并发执行线程和顺序执行线程分别阻塞等待并发指令队列和顺序指令队列中存入指令;

S3:接收到新客户的连接请求时,客户连接监听线程被唤醒,将accept函数返回的新客户的套接字和客户信息更新到全局结构数组中,并向无名管道的写端口pipe[1]写入任意字符使文件集fdSet中的无名管道读端口pipe[0]变为可读状态;接收到已连接的客户通过套接字发送的指令时对应套接字变为可读状态;

S4:客户指令解析线程被唤醒,函数select从文件集fdSet中筛选并只保留其中的可读文件,确认无名管道读端口pipe[0]是否仍在被筛选后的可读文件集fdSet中,若是则清空无名管道的读端口pipe[0]并返回到步骤S2,否则逐个确认全局结构数组中的各客户套接字是否在可读文件集fdSet中,并读取和解析仍在可读文件集fdSet中的套接字的指令内容,将不涉及临界资源的指令缓存至并发指令队列,唤醒并发执行线程读取并执行并发指令队列中的指令,将涉及临界资源的指令缓存至顺序指令队列,唤醒顺序执行线程读取并执行顺序指令队列中的指令;当所有指令均已缓存至指令队列时返回步骤S2。

以下是本申请提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构中的客户连接监听线程的一种代码示例:

该线程先在initialize_listen_socket()函数中创建了阻塞式的监听套接字listenFd,接着调用init_client_fds()初始化全局结构数组gszClient,然后循环调用acceept()监听已连接的客户并生成新的通信套接字;对代码中画圈的几处做详细解释,由上往下第一处是设置线程属性为PTHREAD_CANCEL_ASYNCHOROUS,保证线程即使在accept()或互斥锁上阻塞时仍能被其它线程调用pthread_cancel异步取消;第二处是监听到新客户时需要向无名管道写端口pListen->szPipeFd[1]写入任意字符或字符串,用来唤醒睡眠因老客户没有发送新指令而睡眠在函数select上的客户指令解析线程以更新新客户套接字到fdSet中;第三处是新客户连接时对信号量sem_ConnectClt进行V操作,保证信号量等于已连接客户数量,客户指令解析线程会对该信号量进行先P操作后V操作,即没有任何客户连接时客户指令解析线程会处于阻塞状态节省CPU调度。

以下是本申请提供的阻塞式异步监听多客户指令并控制多硬件的服务端架构中的客户指令解析线程的主要部分的一种代码示例:

对代码中画圈的几处做详细解释,由上往下第一处对信号量sem_ConnectClt先进行P操作再V操作,保证sem_ConnectClt数量等于已连接的客户数且没有客户连接时该线程将处于休眠状态,以节省CPU调度;第二处先获取信号量值得到已连接客户数量,然后调用Statistic_ConnectedClient函数统计在监听线程中标记保存在gszClient中的已连接客户,并将所有的已连接客户通信套接字和无名管道的读端口szPipe[0]加入文件集comFdSet进行监视,调用函数select筛选可读套接字,一旦监听线程有新客户连接会向无名管道写读端口写数据从而唤醒睡眠在函数select上的本线程,从而实时更新函数select监视的已连接客户;第三处则是及时清空读端口方便下一次正确唤醒;第四处则是循环调用Search_ReadableClient,按序返回全局结构数组gszClient中可读客户数组的结构体地址依次进行后续的读取解析。

需要说明的是,虽然上文按照特定顺序描述了各个步骤,但是并不意味着必须按照上述特定顺序来执行各个步骤,实际上,这些步骤中的一些可以并发执行,甚至改变顺序,只要能够实现所需要的功能即可。这里说明的设备数量和处理规模是用来简化本发明的说明的,对本发明的应用、修改和变化对本领域的技术人员来说是显而易见的。

尽管本发明的实施方案已公开如上,但其并不仅仅限于说明书和实施方式中所列运用,它完全可以被适用于各种适合本发明的领域,对于熟悉本领域的人员而言,可容易地实现另外的修改,因此在不背离权利要求及等同范围所限定的一般概念下,本发明并不限于特定的细节和这里示出与描述的图例。。

相关技术
  • 在不同客户端之间下发音频监听指令的物联网式解决方法
  • 相应于设备之间的距离设定安全等级的服务器装置、客户端装置、通信系统、服务器控制用集成电路、客户端控制用集成电路、连接客户端装置的方法、连接服务器装置的方法、及通信系统连接方法
技术分类

06120116492209