in reply to Re^3: Doing an Input->process->Output cycle with AnyEvent? (was: error: "recursive blocking wait detected")
in thread Doing an Input->process->Output cycle with AnyEvent? (was: error: "recursive blocking wait detected")

Hm. Let me be up-front and say: I don't understand why anyone would voluntarily choose to use an event-driven system on a pre-emptive, multi-tasking operating system. The phrase that comes to mind is: "Like buying a dog and barking yourself".

Really. I don't understand, why anyone would voluntarily choose to use multi-threading in situations when there are lots of interactions between threads. The mess of mutexes and semaphores with really high chance of dead-locking - that's what such application looks like.

The rule is simple. Use tools that are appropriate for the work. If the actions are short and interaction is high, then event-driven system is the best. If the actions take longer time and don't interact much, then multi-threading is your choice. And of course, don't bother with all of this if your application is very simple. This approach will speed up the execution and simplify the development. All you need is good understanding of the event-driven approach.

  • Comment on Re^4: Doing an Input->process->Output cycle with AnyEvent? (was: error: "recursive blocking wait detected")

Replies are listed 'Best First'.
Re^5: Doing an Input->process->Output cycle with AnyEvent? (was: error: "recursive blocking wait detected")
by BrowserUk (Patriarch) on Oct 20, 2010 at 09:29 UTC
    The mess of mutexes and semaphores with really high chance of dead-locking - that's what such application looks like.

    Really? Show me. Or better yet. Show me, (real working code I can download), that does something (other than GUI or webserver), for which you believe that an event-driven architecture is the right tool for the job.

    In return, I'll try to reproduce that using threads, without the need for a "mess of mutexes and semaphores".

    All you need is good understanding of the event-driven approach.

    Please believe me when I tell you that I do understand event-driven architectures.

    • From 6502-based assembler controlling z80-based OMR readers;
    • to IBM PCs running DOS talking 3270 protocol to System/38s via 3274 controllers;
    • to doing concurrent, bulk data transfers to and from up to 64 hand-held terminals via serial ports from C code under DOS.

    It is exactly because I've done it, and then had to go through the pain of re-tuning it (the last project above), to run on faster hardware. And then add more ports and re-tune again. And then add a remote monitoring and control channel via modem, and the re-tune the whole, internecine monster all over again.

    It is exactly because of that, that I don't understand why any one would choose the architecture if they had a choice.

    It worked, and worked well (most of the time). But sheesh! Was it ever a bitch to maintain, upgrade and debug.

    Latterly on the above project I ported it to OS/2 and used threading. What a joy. Simple, linear flows: read-ack-read-ack-read-nak-write ack. Add more ports, start more threads. Waiting for IO, just block. Need an accurate time window, raise your priority and sleep for the required number of milliseconds. Someone dials in, start a thread to talk to them. Each thread has it's own context and its own stack. No constantly shuffling data in and out of global stores each time you have to deal with something else.

    Really, I've done it both ways, and I know which is easier to write, maintain and debug. Or at least, I believe I do. So prove me wrong?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      I would point you towards the "other" event oriented protocols, like irc clients. They and the protocol lend themselves well towards event oriented approaches. But they are quite similar to webservers in their nature anyway.

      Maybe all systems where events come in and get dispatched are such a class? Although I see the advantage if you have multiple clients and more complex interactions than request -> response, where the linear flow in programming is preferrable over the event oriented approach, where you stitch together the flow by keeping some additional state.

        Obviously there are some applications for which an event driven architecture is the natural fit. My exclusion of GUIs and asynchronous communications servers (what I should have said when I said web-servers), is a tacit admission of that. But even in these, not all their functionality naturally lends itself to being event driven.

        In the case of GUIs, their primary purpose is to display information and allow the user to interact with that display. But teh data has to come from somewhere; or go somewhere; and often has to be manipulated in CPU-intensive ways as a result of the interactions. And if you've ever had your GUI freeze up whilst it renders a print job or recalculates your data or parses gigabytes of data from the wrong file, you'll understand that doing these things in-line with the GUI handling code is not a good idea. Sure, it is possible to break up these processes into iddy-biddy chunks such that you can check if the user wants to use the GUI every 1/10th of a second, but that just complicates everything and slows down the long-running processing even further. Pushing such processing off into a background thread is no-brainer. But most (all?) of the event-driven frameworks preclude such simple and obvious techniques.

        Even web-servers occasionally have to upload or download a file, or perform some long-running, server-side processing on behalf of individual clients. It is far easier to spawn a thread (or a process), with a client-dedicated, non-http socket, to handle these things, than it is to try and juggle multiple, concurrent such processing through a single event-loop. If the frameworks would only let you.

        IRC clients are an interesting case. In effect, they are both multiple-server clients, and a (peer-2-peer) server. And although an event-driven architecture seems a natural fit, I do wonder (I've never actually written one), if, given their nature, a threads + queue architecture isn't a better fit?

        Given that most IRC users will be talking to at most, low-10s of servers and peers; and generally such connections will be relatively long running, neither spawn-times nor memory usage are of any particular concern. One inbound queue to the C/GUI component gathers inbound messages for display. With the CUI acting as the dispatcher, routing user input to the appropriate output socket. Then all you need is a single semaphore per server or peer, to ensure that you don't try to read & write concurrently to the same socket, and the picture is complete. One day I'll have to go through that rite-of-passage, and write one to see how the architecture pans out.

        Anyway, I know you know all of this--even if you're not so anti-framework as I am--but it is nice to get counterpoint.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.