Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » Coffee corner » Thoughts about alternative approach to multithreading
Re: Thoughts about alternative approach to multithreading [message #19205 is a reply to message #19203] Thu, 20 November 2008 10:42 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11712
Registered: November 2005
Ultimate Member
Mindtraveller wrote on Thu, 20 November 2008 04:19

If I understand your example right...



I guess you do not.

The goal is to create single-machine memcached server - or simple version of it, but multithreaded.

Anyway, I guess, it is still bad example. Frankly, it is really hard to come with good *simple* example....

If you have any idea, I might try as well... Smile

Mirek
Re: Thoughts about alternative approach to multithreading [message #19847 is a reply to message #19205] Tue, 27 January 2009 00:06 Go to previous messageGo to next message
Mindtraveller is currently offline  Mindtraveller
Messages: 916
Registered: August 2007
Location: Russia, Moscow rgn.
Experienced Contributor

Finally I`ve finished some controller programming work and resumed developing of "alternative MT-approach" class.
Let`s summarize the idea. To avoid synchronization objects headache and possible synchronization issues it is proposed to make all the threads isolated from each other. It means that
* threads do not "see" each other`s variables (including global ones, the ones with atomic access and shared synchronization objects) - it fully conforms classic OOP approach.
* threads do not call other thread`s member functions directly
* the only possible threads interaction is made through sending some message into thread`s internal queue.

Generally this would make threads interactions far more predictable and debuggable.
After some thinking I`ve made a decision not to send messages but instead send requests to run thread public member function (callback). It was decided because "message" is actually a signal to do some job. So it is no need to create any artificial message identifiers while you directly request to execute these callbacks.

It looks like this:
class JobThread1 : public CallbackThread
{
public: //these members may be added into thread queue and must not be called directly
    void Job11();
    void Job12(const String &);
private: //all the realization details are private
    //...
};

class class JobThread2 : public CallbackThread
{
public: //these members may be added into thread queue and must not be called directly
    void Job21(const String &);
private: //all the realization details are private
    //...
};

CONSOLE_APP_MAIN
{
    JobThread1 jobs1;
    JobThread2 jobs2;

    for (int i=0; i<10; ++i)
    {
        jobs1.Add(&JobThread1::Job11);
        jobs1.Add(&JobThread1::Job12, FormatInt(i));
        jobs2.Add(&JobThread2::Job21, FormatIntHex(i));
    }
};


You may even treat main thread as the same alt-MT thread. To do this you may have CallbackQueue variable and request it`s tasks. These tasks are processed with CallbackQueue::DoTasks().

Below is ready-to-use class with a simple test code.
If you are interested you may download and test it, or even use it in your apps. I hope more advanced versions of class will come soon (a number of optimizations is yet to be made).

"Alternative" MT requires a bit of reengineering threads processing functions. To make alt-MT program, you should think differently. Now you can`t share variables, now you don`t have a number of routines which are called in unpredictable sequence.

Instead you have messaging queues which mustn`t hold big number of messages (it is possible though not recommended). This means that thread must be logically solid as much as possible. This would keep all "tiny" interactions inside one thread.

Of course there are situations where "classic" MT with sync objects fits better. Situations include threads exchange with a huge number of tiny messages (inc/dec some variable). So if you cannot divide threads interaction into a (relatively small) number of (relatively medium) jobs - use "classic" MT.

I mean if you use more than 100`000 of messages per second - just use sync objects instead. But now you at least may choose to think "new way" on reorganizing threads member functions to make program stable or continue interacting with shared global variables to make it possibly quicker and less memory consuming but harder to debug and potentially less stable.

[Updated on: Tue, 27 January 2009 09:11]

Report message to a moderator

Re: Thoughts about alternative approach to multithreading [message #22314 is a reply to message #19847] Fri, 03 July 2009 10:23 Go to previous messageGo to next message
Mindtraveller is currently offline  Mindtraveller
Messages: 916
Registered: August 2007
Location: Russia, Moscow rgn.
Experienced Contributor

luzr wrote on Tue, 30 June 2009 00:15

Well, I have some experiences now (did project based on queues, now planning to rewrite it to plain old locking) and I have something to say about the topic (IMO!):

Synchronization objects are simple to manage as compared to often complex race condition relations in queued systems.

What do mean exactly, could you please give a pair of examples why you switched back from queueing model? This is very important topic IMO.

I personally found them very comfortable and stable comparing to a tonns of mutexes.

[Updated on: Fri, 03 July 2009 10:24]

Report message to a moderator

Re: Thoughts about alternative approach to multithreading [message #22326 is a reply to message #22314] Fri, 03 July 2009 18:49 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11712
Registered: November 2005
Ultimate Member
Mindtraveller wrote on Fri, 03 July 2009 04:23

luzr wrote on Tue, 30 June 2009 00:15

Well, I have some experiences now (did project based on queues, now planning to rewrite it to plain old locking) and I have something to say about the topic (IMO!):

Synchronization objects are simple to manage as compared to often complex race condition relations in queued systems.

What do mean exactly, could you please give a pair of examples why you switched back from queueing model? This is very important topic IMO.

I personally found them very comfortable and stable comparing to a tonns of mutexes.


I would like to, but right now I seem to be unable to describe it right. The problem was that it was user driven application and there are problems basically with "queue lag".

Maybe that the heart of problem is (was) the fact that it worked in "post" mode (not "execute") - messages (callbacks) being posted and not waiting for completition. Too often I ended with wrong events in the queue...

BTW, without posting, your method is equivalent to one mutex per instance and locking for any method call...

Mirek
Re: Thoughts about alternative approach to multithreading [message #22339 is a reply to message #22326] Sun, 05 July 2009 21:43 Go to previous messageGo to next message
Mindtraveller is currently offline  Mindtraveller
Messages: 916
Registered: August 2007
Location: Russia, Moscow rgn.
Experienced Contributor

luzr wrote on Fri, 03 July 2009 20:49

I would like to, but right now I seem to be unable to describe it right. The problem was that it was user driven application and there are problems basically with "queue lag".

Maybe that the heart of problem is (was) the fact that it worked in "post" mode (not "execute") - messages (callbacks) being posted and not waiting for completition. Too often I ended with wrong events in the queue...

BTW, without posting, your method is equivalent to one mutex per instance and locking for any method call...

Mirek


1. What do you mean by "queue lag"? In my case case calling asynchronouse callback (this means: copy arguments, awake thread, post arguments and start execution), is almost as quick as calling U++ callback (I`ve posted these results above).
Personally I denied ANY types of events because I consider them absolutely artifical. The only thing which is really needed is executing some callback. So I had no problems identifying any types of events. I will appreciate any example where this approach fails (of course avoiding boundaries mentioned).

To be more precise, I takes more than single mutex per thread as there`s a queue and it really needs a semaphore.
Re: Thoughts about alternative approach to multithreading [message #22341 is a reply to message #22339] Sun, 05 July 2009 22:08 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11712
Registered: November 2005
Ultimate Member
Mindtraveller wrote on Sun, 05 July 2009 15:43

luzr wrote on Fri, 03 July 2009 20:49

I would like to, but right now I seem to be unable to describe it right. The problem was that it was user driven application and there are problems basically with "queue lag".

Maybe that the heart of problem is (was) the fact that it worked in "post" mode (not "execute") - messages (callbacks) being posted and not waiting for completition. Too often I ended with wrong events in the queue...

BTW, without posting, your method is equivalent to one mutex per instance and locking for any method call...

Mirek


1. What do you mean by "queue lag"? In my case case calling asynchronouse callback (this means: copy arguments, awake thread, post arguments and start execution), is almost as quick as calling U++ callback (I`ve posted these results above).



It is not about performance, but about race conditions.

Quote:


Personally I denied ANY types of events because I consider them absolutely artifical. The only thing which is really needed is executing some callback. So I had no problems identifying any types of events. I will appreciate any example where this approach fails (of course avoiding boundaries mentioned).



Queued callbacks and events are equivalent here.

Well, I will try to describe the example. The code was image viewer. GUI thread to manage gui and other threads to do background loading.

Background threads do loading of whole directories in advance. Now the problem was that they got events to load directory, started performing it and meanwhile user switches to another directory.

With shared access (with mutex), this is quite easily manageable (I mean, stopping loading and doing something else). With queues, not so much.

Also, the fact that I need to pass all info using events is not very handy. With new U++ GUI threading, it is much easier to read actual GUI status in the background thread and adjust GUI as needed.
Re: Thoughts about alternative approach to multithreading [message #22342 is a reply to message #22339] Sun, 05 July 2009 22:10 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11712
Registered: November 2005
Ultimate Member
Quote:


To be more precise, I takes more than single mutex per thread as there`s a queue and it really needs a semaphore.


I meant that if only operation you do is the one that is waiting for the result, it the same as locking instance mutex, calling method, unlocking the mutex.

Of course, not waiting for the result needs queue and semaphore.

Mirek
Re: Thoughts about alternative approach to multithreading [message #22410 is a reply to message #22341] Sat, 11 July 2009 16:06 Go to previous messageGo to next message
Mindtraveller is currently offline  Mindtraveller
Messages: 916
Registered: August 2007
Location: Russia, Moscow rgn.
Experienced Contributor

Example you proposed sets a kind of problem. I spent some days thinking about it (I really met kind of this problem while programmed last project) and came to conclusion that each CallbackQueue/CallbackThread class should be descendant of CallbackNotifier class. Where CallbackNotifier is simply a Map<K,T> and a Mutex to synchronize access from multiple threads. This will enable asynchronouse messaging while thred's current queue callback is being executed. This is of course something from "classic" approach but anyway hides synchronization mutex.

In your example you will i.e. have to check this Map for current directory once per second. And if it is so, remove directory from Map and exit callback.

[Updated on: Sat, 11 July 2009 16:08]

Report message to a moderator

Re: Thoughts about alternative approach to multithreading [message #22411 is a reply to message #22410] Sun, 12 July 2009 08:37 Go to previous message
mirek is currently offline  mirek
Messages: 11712
Registered: November 2005
Ultimate Member
Mindtraveller wrote on Sat, 11 July 2009 10:06

Example you proposed sets a kind of problem. I spent some days thinking about it (I really met kind of this problem while programmed last project) and came to conclusion that each CallbackQueue/CallbackThread class should be descendant of CallbackNotifier class. Where CallbackNotifier is simply a Map<K,T> and a Mutex to synchronize access from multiple threads. This will enable asynchronouse messaging while thred's current queue callback is being executed. This is of course something from "classic" approach but anyway hides synchronization mutex.

In your example you will i.e. have to check this Map for current directory once per second. And if it is so, remove directory from Map and exit callback.


I think this is very much what I have ended with. But it is not a simple and clean design by any definition; the hurdle with locking mutex(es) just seems a much less evil here.

Mirek
Previous Topic: subversion client recommendation
Next Topic: Google Chrome Operative System
Goto Forum:
  


Current Time: Sat Feb 23 07:30:26 CET 2019

Total time taken to generate the page: 0.00875 seconds