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

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

问题描述

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

这个状态机有这些转换;

Connect,LogIn,Query,LogOut,Disconnect

和这些状态;

开始,连接,连接,登录,LoggedIn,Querying,QueryDone,LoggingOut,LoggedOut,Disconnecting,Disconnected

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

我想能够发送几个事件(命令)到此机器(如Connect,LogIn,Query(productA),Query(productB),LogOut,LogIn,Query(productC),LogOut,Disconnect) / strong>并让它处理它们。我不想阻止等待计算机完成处理我发送给它的所有事件。问题是它们必须与上述网络事件交织以通知机器关于正在下载的URL。没有交错机器不能提前其状态(并且处理我的事件),因为从* ing到* ed仅在接收到网络类型的事件之后发生。

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.

实现我的设计目标?

EDIT


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

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

  3. 查看我对此问题的回答 ,其中详细描述了我当前的设计。

  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


  • 更强大

  • 更简单


推荐答案

状态机有一个事件队列。排队事件,开始处理第一个事件,并且当完成时,将下一个事件从队列中拉出并开始。因此,不是状态机直接由客户端代码驱动,而是由队列驱动。

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天全站免登陆