面对无阻塞I / O时如何设计状态机? [英] How to design a state machine in face of non-blocking I/O?

查看:155
本文介绍了面对无阻塞I / O时如何设计状态机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的Qt框架默认情况下是非阻塞I / O来开发通过几个网页(网上商店)浏览的应用程序,并在这些页面上执行不同的操作。我将特定网页映射到我用来浏览此页面的状态机。

此状态机具有这些转换;

连接,LogIn,Query,LogOut,Disconnect

和这些状态;

启动,连接,连接,登录,登录,查询,QueryDone,LoggingOut,LoggedOut,Disconnecting,Disconnected

从* ing转换为* ed状态( Connecting->已连接),是由于 c> LoadFinished 异常网络事件从网络对象接收当当前请求的url被加载。从* ed到* ing状态的转换( Connected-> LoggingIn )是由于我发送的事件。

我想要发送本机的几个事件(命令)(如Connect,LogIn,Query(productA),Query(productB),LogOut,LogIn,Query(productC),LogOut,Disconnect)强>并处理它们。我不想阻止等待机器完成处理我发送给它的所有事件。问题是它们必须与上述网络事件交错通知机器下载的URL。没有交错机器无法提升其状态(并且处理我的事件),因为从* ing到* ed的进行仅在接收到网络类型的事件之后发生。



实现我的设计目标?



编辑


  1. 我正在使用的状态机有自己的事件循环,事件不排队,所以如果机器忙时,机器可能会丢失。

  2. 网络I / O事件不会直接发布到状态机和我正在使用的事件队列。他们被发布到我的代码(处理程序),我必须处理它们。我可以转发他们,但请记住备注否。 1。

  3. 查看我的答案,我详细介绍了我目前的设计。问题是,如果我可以通过这种方式改进这种设计




    • 更强大的

    • 更简单



解决方案

状态机有一个事件队列。排队事件,开始处理第一个事件,当这个完成时,将下一个事件从队列中拉出,然后开始。因此,代替直接由客户端代码驱动的状态机,它由队列驱动。



这意味着任何涉及使用一个转换结果的逻辑下一个必须在机器中。例如,如果登录完成页面告诉您下一步去哪里。如果这是不可能的,那么事件可能包括机器可以调用的回调,以返回任何需要知道的内容。


I'm using Qt framework which has by default non-blocking I/O to develop an application navigating through several web pages (online stores) and carrying out different actions on these pages. I'm "mapping" specific web page to a state machine which I use to navigate through this page.
This state machine has these transitions;
Connect, LogIn, Query, LogOut, Disconnect
and these states;
Start, Connecting, Connected, LoggingIn, LoggedIn, Querying, QueryDone, LoggingOut, LoggedOut, Disconnecting, Disconnected
Transitions from *ing to *ed states (Connecting->Connected), are due to LoadFinished asynchronous network events received from network object when currently requested url is loaded. Transitions from *ed to *ing states (Connected->LoggingIn) are due to events send by me.
I want to be able to send several events (commands) to this machine (like Connect, LogIn, Query("productA"), Query("productB"), LogOut, LogIn, Query("productC"), LogOut, Disconnect) at once and have it process them. I don't want to block waiting for the machine to finish processing all events I sent to it. The problem is they have to be interleaved with the above mentioned network events informing machine about the url being downloaded. Without interleaving machine can't advance its state (and process my events) because advancing from *ing to *ed occurs only after receiving network type of event.

How can I achieve my design goal?

EDIT

  1. The state machine I'm using has its own event loop and events are not queued in it so could be missed by machine if they come when the machine is busy.
  2. Network I/O events are not posted directly to neither the state machine nor the event queue I'm using. They are posted to my code (handler) and I have to handle them. I can forward them as I wish but please have in mind remark no. 1.
  3. Take a look at my answer to this question where I described my current design in details. The question is if and how can I improve this design by making it

    • More robust
    • Simpler

解决方案

Sounds like you want the state machine to have an event queue. Queue up the events, start processing the first one, and when that completes pull the next event off the queue and start on that. So instead of the state machine being driven by the client code directly, it's driven by the queue.

This means that any logic which involves using the result of one transition in the next one has to be in the machine. For example, if the "login complete" page tells you where to go next. If that's not possible, then the event could perhaps include a callback which the machine can call, to return whatever it needs to know.

这篇关于面对无阻塞I / O时如何设计状态机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆