Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Multithreaded code is ridiculous

Multithreaded code is ridiculous

Scheduled Pinned Locked Moved The Lounge
designalgorithmsregextutorialquestion
53 Posts 18 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    honey the codewitch
    wrote on last edited by
    #1

    So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

    Real programmers use butterflies

    Greg UtasG C P M R 14 Replies Last reply
    0
    • H honey the codewitch

      So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

      Real programmers use butterflies

      Greg UtasG Offline
      Greg UtasG Offline
      Greg Utas
      wrote on last edited by
      #2

      Well, I'm a longstanding member of the choir that you're preaching to. :laugh: If it's a thread pool, I have them share a work queue. You seem to imply that you queue messages against threads even in this case, but I doubt it. I only queue messages on a thread when it's the only one handling that kind of work.

      Robust Services Core | Software Techniques for Lemmings | Articles

      <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
      <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

      H R 2 Replies Last reply
      0
      • H honey the codewitch

        So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

        Real programmers use butterflies

        C Offline
        C Offline
        CodeWraith
        wrote on last edited by
        #3

        Been there, done that. And had my 3D stuff running in the background. UI and the 3D engine scripted with XAML.

        I have lived with several Zen masters - all of them were cats. His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.

        H 1 Reply Last reply
        0
        • Greg UtasG Greg Utas

          Well, I'm a longstanding member of the choir that you're preaching to. :laugh: If it's a thread pool, I have them share a work queue. You seem to imply that you queue messages against threads even in this case, but I doubt it. I only queue messages on a thread when it's the only one handling that kind of work.

          Robust Services Core | Software Techniques for Lemmings | Articles

          H Offline
          H Offline
          honey the codewitch
          wrote on last edited by
          #4

          What I'm doing is I'm queuing up tasks. In the demo each time a user clicks a button (in order to queue up a new task) the code looks for an available worker. If it doesn't have one, and it can create a new one (and consequently a new thread) then it will. Otherwise if there are already a maximum number of workers created it will choose one of the busy workers to handle the next task. All of the workers do the same task. Think of this like a server application that accepts a limited number of incoming requests into a pool of workers, but will then queue requests after the limit is exceeded among the busy workers. One of them will pick it up as soon as it's finished with what it's doing. Make sense? I hope it does! :~ ETA: Wait, I think I see what you mean by using one queue. I'll have to think on this.

          Real programmers use butterflies

          Greg UtasG U A 3 Replies Last reply
          0
          • C CodeWraith

            Been there, done that. And had my 3D stuff running in the background. UI and the 3D engine scripted with XAML.

            I have lived with several Zen masters - all of them were cats. His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.

            H Offline
            H Offline
            honey the codewitch
            wrote on last edited by
            #5

            Yeah, I mean, I can do it real world, but it's even harder to do it simple enough that it can be used to instruct. That's part of what my rant was about. :)

            Real programmers use butterflies

            C 1 Reply Last reply
            0
            • H honey the codewitch

              Yeah, I mean, I can do it real world, but it's even harder to do it simple enough that it can be used to instruct. That's part of what my rant was about. :)

              Real programmers use butterflies

              C Offline
              C Offline
              CodeWraith
              wrote on last edited by
              #6

              Instructing? I have done a bit of that, but you would not like my methods. :-) Edit: I think, some of my instructors would also have loved to send me to the ghost guard. Tenty times. :-) (What Did You Say, Sergeant? - YouTube[^])

              I have lived with several Zen masters - all of them were cats. His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.

              H 1 Reply Last reply
              0
              • H honey the codewitch

                What I'm doing is I'm queuing up tasks. In the demo each time a user clicks a button (in order to queue up a new task) the code looks for an available worker. If it doesn't have one, and it can create a new one (and consequently a new thread) then it will. Otherwise if there are already a maximum number of workers created it will choose one of the busy workers to handle the next task. All of the workers do the same task. Think of this like a server application that accepts a limited number of incoming requests into a pool of workers, but will then queue requests after the limit is exceeded among the busy workers. One of them will pick it up as soon as it's finished with what it's doing. Make sense? I hope it does! :~ ETA: Wait, I think I see what you mean by using one queue. I'll have to think on this.

                Real programmers use butterflies

                Greg UtasG Offline
                Greg UtasG Offline
                Greg Utas
                wrote on last edited by
                #7

                You said you round-robin, which sounds fine for what you're doing. I use work queues because items aren't lost if a thread fails, there can be queues for different priorities, and some work items may take longer than others. None of these are issues for your demo, though.

                Robust Services Core | Software Techniques for Lemmings | Articles

                <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                H 1 Reply Last reply
                0
                • C CodeWraith

                  Instructing? I have done a bit of that, but you would not like my methods. :-) Edit: I think, some of my instructors would also have loved to send me to the ghost guard. Tenty times. :-) (What Did You Say, Sergeant? - YouTube[^])

                  I have lived with several Zen masters - all of them were cats. His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.

                  H Offline
                  H Offline
                  honey the codewitch
                  wrote on last edited by
                  #8

                  Do they involve beating the stupid out of students? :-D

                  Real programmers use butterflies

                  C 1 Reply Last reply
                  0
                  • Greg UtasG Greg Utas

                    You said you round-robin, which sounds fine for what you're doing. I use work queues because items aren't lost if a thread fails, there can be queues for different priorities, and some work items may take longer than others. None of these are issues for your demo, though.

                    Robust Services Core | Software Techniques for Lemmings | Articles

                    H Offline
                    H Offline
                    honey the codewitch
                    wrote on last edited by
                    #9

                    Well it turns out you were right, and I could get away with a single shared server queue in this case. Thanks for that. I guess I was just following a pattern without thinking hard enough about it. I use queues, but not priority queues because the code is already complicated enough. I could probably implement a thread safe priority queue but it's not something i want to do. ;P

                    Real programmers use butterflies

                    Greg UtasG R 2 Replies Last reply
                    0
                    • H honey the codewitch

                      Do they involve beating the stupid out of students? :-D

                      Real programmers use butterflies

                      C Offline
                      C Offline
                      CodeWraith
                      wrote on last edited by
                      #10

                      Only once. The idiot started to turn around to me with a loaded machine pistol in his hands. Safety set to 'A', as in 'Amen'. I edited the last post. The little video is funnier than this story.

                      I have lived with several Zen masters - all of them were cats. His last invention was an evil Lasagna. It didn't kill anyone, and it actually tasted pretty good.

                      1 Reply Last reply
                      0
                      • H honey the codewitch

                        Well it turns out you were right, and I could get away with a single shared server queue in this case. Thanks for that. I guess I was just following a pattern without thinking hard enough about it. I use queues, but not priority queues because the code is already complicated enough. I could probably implement a thread safe priority queue but it's not something i want to do. ;P

                        Real programmers use butterflies

                        Greg UtasG Offline
                        Greg UtasG Offline
                        Greg Utas
                        wrote on last edited by
                        #11

                        Just to clarify. I don't use a priority queue, but a separate queue for each priority level.

                        Robust Services Core | Software Techniques for Lemmings | Articles

                        <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                        <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                        H 1 Reply Last reply
                        0
                        • Greg UtasG Greg Utas

                          Just to clarify. I don't use a priority queue, but a separate queue for each priority level.

                          Robust Services Core | Software Techniques for Lemmings | Articles

                          H Offline
                          H Offline
                          honey the codewitch
                          wrote on last edited by
                          #12

                          fair enough. :)

                          Real programmers use butterflies

                          1 Reply Last reply
                          0
                          • H honey the codewitch

                            So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

                            Real programmers use butterflies

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #13

                            Yeah, that sounds wrong. One shared queue tends to work best.

                            H 1 Reply Last reply
                            0
                            • P PIEBALDconsult

                              Yeah, that sounds wrong. One shared queue tends to work best.

                              H Offline
                              H Offline
                              honey the codewitch
                              wrote on last edited by
                              #14

                              I ended up changing it so it did it with one queue. I just lost in engineering tunnel vision for a bit, though eliminating the individual pipelines means I lose control over who the message goes to.

                              Real programmers use butterflies

                              P 1 Reply Last reply
                              0
                              • H honey the codewitch

                                I ended up changing it so it did it with one queue. I just lost in engineering tunnel vision for a bit, though eliminating the individual pipelines means I lose control over who the message goes to.

                                Real programmers use butterflies

                                P Offline
                                P Offline
                                PIEBALDconsult
                                wrote on last edited by
                                #15

                                Threads are fungible.

                                H 1 Reply Last reply
                                0
                                • P PIEBALDconsult

                                  Threads are fungible.

                                  H Offline
                                  H Offline
                                  honey the codewitch
                                  wrote on last edited by
                                  #16

                                  Most of the time, but in this case, one thread is potentially multifunction meaning for example, you might care about which one you stop since one might be doing a job you're still interested in! In the end I didn't go that route because it made everything too complicated for demonstration purposes.

                                  Real programmers use butterflies

                                  1 Reply Last reply
                                  0
                                  • H honey the codewitch

                                    So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

                                    Real programmers use butterflies

                                    M Offline
                                    M Offline
                                    Mircea Neacsu
                                    wrote on last edited by
                                    #17

                                    Quote:

                                    o as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique.

                                    It's called a producer-consumer model and it's generally not so hard to handle. In most cases you need just one queue and all consumers feed from it. No rule that says a consumer cannot be a producer also. Consumers need to be polivalent meaning they know how handle any task that they pick from the queue. If you have task-oriented consumers that know how to do only one task (sometimes called fussy-eaters) you're beter off with multiple queues and and each consumer waits in the appropriate queue.

                                    Mircea

                                    H 1 Reply Last reply
                                    0
                                    • H honey the codewitch

                                      Well it turns out you were right, and I could get away with a single shared server queue in this case. Thanks for that. I guess I was just following a pattern without thinking hard enough about it. I use queues, but not priority queues because the code is already complicated enough. I could probably implement a thread safe priority queue but it's not something i want to do. ;P

                                      Real programmers use butterflies

                                      R Offline
                                      R Offline
                                      raddevus
                                      wrote on last edited by
                                      #18

                                      These issues you are discussing related to multi-threaded programming really are a problem. It's amazing how it originally seemed like multi-threaded programming was the panacea but just became another problem. :) Because it is so difficult a new thing has arisen: The Actor Model. Basically, it is a way to say that you have some work that should be done and you set an Actor to doing that work. It will be done concurrently and then let you know when it is done. In this way the threading part is abstracted away. One of the main implementations of The Actor Model is called Akka (originally implemented on the JVM). But now there is a .NET Version[^]. That site has a pretty good overview explanation of it all. The Actor Model really does fix a lot of what is wrong with the multi-threaded world. Check it out and see what you think.

                                      1 Reply Last reply
                                      0
                                      • Greg UtasG Greg Utas

                                        Well, I'm a longstanding member of the choir that you're preaching to. :laugh: If it's a thread pool, I have them share a work queue. You seem to imply that you queue messages against threads even in this case, but I doubt it. I only queue messages on a thread when it's the only one handling that kind of work.

                                        Robust Services Core | Software Techniques for Lemmings | Articles

                                        R Offline
                                        R Offline
                                        raddevus
                                        wrote on last edited by
                                        #19

                                        Greg Utas wrote:

                                        Well, I'm a longstanding member of the choir that you're preaching to.

                                        I agree. that's why if I had to do anything that really did heavy multi-threading (as a service or back-end type thing -- not just in a WinForm app) then I would use the new thing: Akka (which implements the Actor Model[^]. I've actually used it one time and it is quite amazing once you get past the learning curve. There's more on that landing page but read this quick summary that really is as good as it sounds.

                                        Akka site says:

                                        Actor Model The Actor Model provides a higher level of abstraction for writing concurrent and distributed systems. It alleviates the developer from having to deal with explicit locking and thread management, making it easier to write correct concurrent and parallel systems.

                                        There are some nice simple diagrams there that show how it works.

                                        N Greg UtasG 2 Replies Last reply
                                        0
                                        • H honey the codewitch

                                          So as an instructional article I'm preparing code that can enqueue work items to a limited number of threads. If all the threads are busy and there's no more thread creation allowed (say you have a 3 thread limit) then one of the threads that's already busy enqueues the next message for when it's done with what it's currently processing. It schedules among the already busy threads using a round robin technique. The whole thing works using message passing and message queues. That's how the threads communicate with each other. You can post messages to each of the threads. The trouble with it is the complexity of it snowballs. All of the sudden I need to sync the UI which requires a whole separate layer. And then there's the interthread communication that's already complicated. There's only so much I can fit into an article without overwhelming the reader, and to produce anything approaching a real world example requires so much complicated code that it's just silly. Oh you did this over here? Well you need to synchronize over there. And because you did that, you need to handle it over there too, etc. It's a mess. I really think the approach traditional computers take to preemptive multithreading is an anti-pattern. It feels like every anti-pattern I've ever encountered: The more code you need to make it work, the more code you need to make it work! You end up putting more work into it just to get to the point where you can put more work into it, and everything feels like a workaround.

                                          Real programmers use butterflies

                                          R Offline
                                          R Offline
                                          RickZeeland
                                          wrote on last edited by
                                          #20

                                          Some languages are more suitable for concurrrent programming, see: programming-languages-for-concurrent-programming[^]

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups