Discussion:
How to stop multiple threads properly
(too old to reply)
Dan Berghult
2013-05-13 13:31:42 UTC
Permalink
RB2012r2.1 Mac and Win

Hi,


I have an app where you can configure several tasks.


Each tasks are then performed by an RB thread.


When I quit the app I want each task to be killed nicely:

That is if the task is sleeping: Just kill it and if the thread is running: wait a while then kill the thread.



The approach that I use today is to run another thread which tries to stop the task-threads and sits and waits to kill the long running threads and finally quits the application.


I guess my question is: Should I do this in another way instead? (Timer perhaps)


Or is this the right approach?



Dan

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Glenn L. Austin
2013-05-13 15:12:55 UTC
Permalink
Post by Dan Berghult
RB2012r2.1 Mac and Win
Hi,
I have an app where you can configure several tasks.
Each tasks are then performed by an RB thread.
That is if the task is sleeping: Just kill it and if the thread is running: wait a while then kill the thread.
The approach that I use today is to run another thread which tries to stop the task-threads and sits and waits to kill the long running threads and finally quits the application.
I guess my question is: Should I do this in another way instead? (Timer perhaps)
Or is this the right approach?
Rule #1 of multi-threading: You should NEVER, EVER, EVER (EVER times infinity!) "kill" a thread from outside the thread. That thread *could* have one or more resources "locked" or in-use, and killing the thread means that resource is locked for everyone (or left open instead of being properly closed).

Rule #2 of multi-threading: If you really believe that you have a valid reason for killing one thread from another thread, refer to rule #1.

That being said, you *should* have a "terminate" flag as a part of your thread object, and check it "often" (you decide what "often" means) within the thread. If your thread code detects that the flag is set, terminate as quickly as you can after leaving resource states as unchanged as possible. This way, the thread is in charge of its own clean-up, and you can guarantee proper termination and state. Remember that a computer's reaction to an input may be far faster than the user's -- most users won't consider a 0.1-0.2 second delay in response to be "laggy" -- except in games.

Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't). Of course, all of this "getting" and "setting" is wrapped inside a CriticalSection-based mutex so that the get and set operations within the thread don't get an indeterminate state, and array contents are copied (so are objects that could change throughout the run of the thread). Yes, this does mean a bit more work, but my threads don't deadlock or work with data that is invalid (it could be stale, but that's a different problem entirely
).

Multi-threading isn't easy, but RS does make it easier than it could be.
--
Glenn L. Austin, Computer Wizard and Race Car Driver <><
<http://www.austin-soft.com>


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-13 15:47:58 UTC
Permalink
Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't). Of course, all of this "getting" and "setting" is wrapped inside a CriticalSection-based mutex so that the get and set operations within the thread don't get an indeterminate state, and array contents are copied (so are objects that could change throughout the run of the thread). Yes, this does mean a bit more work, but my threads don't deadlock or work with data that is invalid (it could be stale, but that's a different problem entirely).
The CriticalSection is something I've never used, and I don't know what benefit it offers. I use threads often, and know it's not a good idea to kill it (like killing a process, it's better to ask it to quit), but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Light Blue Software
2013-05-13 15:53:41 UTC
Permalink
Post by Glenn L. Austin
Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't).
See also the cautionary tale at http://thedailywtf.com/Articles/My-Tales.aspx in the 'Finally' story. Never rely on software to undo things if something doesn't work for some reason; make sure that if you have a bunch of changes then everything is changed or nothing is changed.

H

--
admin-nFAfof9qFe+***@public.gmane.org • Twitter: @lighterblue • www.lightbluesoftware.com

Voted 'Best Professional Product of the Year 2012' by members of the SWPP

Light Blue Software is a company registered in England and Wales, number 6671025. Our registered office is 101 Teversham Drift, Cambridge CB1 3LL.











_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Charles Yeomans
2013-05-13 15:59:06 UTC
Permalink
Post by Marnaud
Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't). Of course, all of this "getting" and "setting" is wrapped inside a CriticalSection-based mutex so that the get and set operations within the thread don't get an indeterminate state, and array contents are copied (so are objects that could change throughout the run of the thread). Yes, this does mean a bit more work, but my threads don't deadlock or work with data that is invalid (it could be stale, but that's a different problem entirely).
The CriticalSection is something I've never used, and I don't know what benefit it offers. I use threads often, and know it's not a good idea to kill it (like killing a process, it's better to ask it to quit), but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
You use them to control access to an object by multiple threads.


Charles Yeomans
Glenn L. Austin
2013-05-13 18:43:17 UTC
Permalink
Post by Charles Yeomans
Post by Marnaud
Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't). Of course, all of this "getting" and "setting" is wrapped inside a CriticalSection-based mutex so that the get and set operations within the thread don't get an indeterminate state, and array contents are copied (so are objects that could change throughout the run of the thread). Yes, this does mean a bit more work, but my threads don't deadlock or work with data that is invalid (it could be stale, but that's a different problem entirely).
The CriticalSection is something I've never used, and I don't know what benefit it offers. I use threads often, and know it's not a good idea to kill it (like killing a process, it's better to ask it to quit), but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
You use them to control access to an object by multiple threads.
In the case I describe above, I Enter the CriticalSection before getting/making any changes, and Leave when I'm done. Basically it is making sure that no other thread can read or modify that data while I'm in the middle of a read or modification. Basically (written in Mail):

myGetSetCriticalSection.Enter

' Read or make my changes here

myGetSetCriticalSection.Leave

myGetSetCriticalSection is a property on the class.
--
Glenn L. Austin, Computer Wizard and Race Car Driver <><
<http://www.austin-soft.com>


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Dan Berghult
2013-05-13 19:56:01 UTC
Permalink
Thank you all.

Dan


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-13 19:57:47 UTC
Permalink
Post by Glenn L. Austin
myGetSetCriticalSection.Enter
' Read or make my changes here
myGetSetCriticalSection.Leave
myGetSetCriticalSection is a property on the class.
Let's see how I get it, where I'm wrong. The critical section, in this case, is bound to the object that the thread is about to modify. When entered, and until left, it prevents any other thread from accessing the object and its properties/methods/shared methods (what about events, since they're triggered from the main thread?); would another thread accessing this object get a nil reference, or any modification would be lost (exception raised?)?
Thanks
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Glenn L. Austin
2013-05-13 20:23:42 UTC
Permalink
Post by Marnaud
Post by Glenn L. Austin
myGetSetCriticalSection.Enter
' Read or make my changes here
myGetSetCriticalSection.Leave
myGetSetCriticalSection is a property on the class.
Let's see how I get it, where I'm wrong. The critical section, in this case, is bound to the object that the thread is about to modify. When entered, and until left, it prevents any other thread from accessing the object and its properties/methods/shared methods (what about events, since they're triggered from the main thread?); would another thread accessing this object get a nil reference, or any modification would be lost (exception raised?)?
The myGetSetCriticalSection is a property of the class *instance* (it doesn't modify the class interface at all). It is used to protect certain values within the class -- not the entire class.

So, properties/methods of the class *instance* can be guaranteed outside of the Enter/Leave pair. If a second method attempts to Enter the critical section, that thread is blocked until the thread that has gotten past the Enter calls Leave.

Think of the Enter/Leave pair as flaggers at a construction site. Only one is showing "Slow" -- the rest are showing "Stop." When the one that is showing "Slow" takes down their sign (e.g. changes it to "Stop"), another one can change theirs to "Slow." Only one flagger can be showing "Slow" at any time.

Finally, in response to "shouldn't there be a Try/Catch/Finally in there" -- I do *nothing* but assignments (and copies of the original values) inside the Enter/Leave. For safety's sake, I probably should put them in there, but frankly if an assignment fails you're living on borrowed time anyway.
--
Glenn L. Austin, Computer Wizard and Race Car Driver <><
<http://www.austin-soft.com>


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Jon Ogden
2013-05-14 12:08:00 UTC
Permalink
Sent from my iPhone
Post by Marnaud
(what about events, since they're triggered from the main thread?
I think that is an inaccurate assumption. You can raise events from threads and the code in that event handler will run inside the thread.


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-14 15:10:53 UTC
Permalink
Post by Jon Ogden
I think that is an inaccurate assumption. You can raise events from threads and the code in that event handler will run inside the thread.
Yes, you're right. In fact, I was referring to “external” events (KeyDown, Deactivate, SelChanged, etc.). Since they belong to the UI, I guess (or, at least, I hope) they can't be triggered from a non-main thread.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
d***@public.gmane.org
2013-05-14 17:33:36 UTC
Permalink
Post by Marnaud
Any benefit I'm missing?
Post by Jon Ogden
I think that is an inaccurate assumption. You can raise events from threads and the code in that event handler will run inside the thread.
Yes, you're right. In fact, I was referring to “external” events (KeyDown, Deactivate, SelChanged, etc.). Since they belong to the UI, I guess (or, at least, I hope) they can't be triggered from a non-main thread.
That's probably the benefit. You don't have to care any longer who is calling, including the main thread, if you protect your resource.
And no logic anywhere required to make sure other threads are sleeping. And if you code 6 months later something other which modifies the resource you probably don't have in mind that this resource is also modified by other threads. With a protection you are always safe, no matter what.
Convinced? ;-)

Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-14 21:08:37 UTC
Permalink
Post by d***@public.gmane.org
Post by Marnaud
Any benefit I'm missing?
Post by Jon Ogden
I think that is an inaccurate assumption. You can raise events from threads and the code in that event handler will run inside the thread.
Yes, you're right. In fact, I was referring to “external” events (KeyDown, Deactivate, SelChanged, etc.). Since they belong to the UI, I guess (or, at least, I hope) they can't be triggered from a non-main thread.
That's probably the benefit. You don't have to care any longer who is calling, including the main thread, if you protect your resource.
And no logic anywhere required to make sure other threads are sleeping. And if you code 6 months later something other which modifies the resource you probably don't have in mind that this resource is also modified by other threads. With a protection you are always safe, no matter what.
Convinced? ;-)
Convinced that CriticalSections are very helpful, yes. Convinced that I'll certainly use them the next time I could, I can't predict.
Thank you.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Charles Yeomans
2013-05-13 20:03:41 UTC
Permalink
Post by Glenn L. Austin
Post by Charles Yeomans
Post by Marnaud
Personally, my threads make copies of data that the thread depends upon early in the thread's execution and does all of its work in local variables. When the thread operation is complete, it "pushes" its changes back to the main object so that the object states are maintained and there's no "intermediate" state (some of the data is changed, some isn't). Of course, all of this "getting" and "setting" is wrapped inside a CriticalSection-based mutex so that the get and set operations within the thread don't get an indeterminate state, and array contents are copied (so are objects that could change throughout the run of the thread). Yes, this does mean a bit more work, but my threads don't deadlock or work with data that is invalid (it could be stale, but that's a different problem entirely).
The CriticalSection is something I've never used, and I don't know what benefit it offers. I use threads often, and know it's not a good idea to kill it (like killing a process, it's better to ask it to quit), but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
You use them to control access to an object by multiple threads.
myGetSetCriticalSection.Enter
' Read or make my changes here
myGetSetCriticalSection.Leave
myGetSetCriticalSection is a property on the class.
Shouldn't there be a try-finally block in this?


Charles Yeomans
d***@public.gmane.org
2013-05-14 07:02:03 UTC
Permalink
(...) but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
A practical example is my logging-class. The CriticalSection ensures that always only one thread at a time can open-write-close the logfile.
Basically, any data which can be modified by different threads needs a protection to ensure that the data is only modified at a whole, or in chunks that make sense.

Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-14 08:37:53 UTC
Permalink
Post by d***@public.gmane.org
(...) but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
A practical example is my logging-class. The CriticalSection ensures that always only one thread at a time can open-write-close the logfile.
Basically, any data which can be modified by different threads needs a protection to ensure that the data is only modified at a whole, or in chunks that make sense.
Thanks for your answer.
I get the idea, but without ever tried, I don't fully understand yet.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
d***@public.gmane.org
2013-05-14 10:36:06 UTC
Permalink
Post by Marnaud
Post by d***@public.gmane.org
(...) but I've never felt the need to use CriticalSections or similar semaphores. For what exactly do you use them?
A practical example is my logging-class. The CriticalSection ensures that always only one thread at a time can open-write-close the logfile.
Basically, any data which can be modified by different threads needs a protection to ensure that the data is only modified at a whole, or in chunks that make sense.
Thanks for your answer.
I get the idea, but without ever tried, I don't fully understand yet.
In case of the logfile, a thread who attempts to write to it might fail because the file might be already open for write access from another thread.

In case of some data, imagine your threads append/modify data to a memory block/array/database/whatever. Especially when the thread iterates through a loop to do it's append- or modify-operation, another thread might come in, interrupting the first one, and starts writing whatever data he has. Now both threads are working at the 'same' time on the data, corrupting the data.


Imagine you have to write a block of data and 10 items in order make one consistent data block:

Thread1:
for i as integer = 1 to 10 ' a context switch to any other thread might occur anytime
array.append thread1Data(i)
next

Thread2:
for i as integer = 1 to 10 ' a context switch to any other thread might occur anytime
array.append thread2Data(i)
next

Very likely to occur:
Thread1's i is 5. The data is half appended. Thread2 becomes active, starts appending data to the same array. Now the data is already corrupted. You end up with 20 items in your array which are in a total unpredictable order since you never know when context switches occur.

If the array is protected, any thread who wants to modify the array will say "knock knock, someone already in here?". And if there's another thread busy on the array, he will just wait until the other thread has finished it's work on the array.


Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-14 15:08:55 UTC
Permalink
Post by d***@public.gmane.org
In case of the logfile, a thread who attempts to write to it might fail because the file might be already open for write access from another thread.
In case of some data, imagine your threads append/modify data to a memory block/array/database/whatever. Especially when the thread iterates through a loop to do it's append- or modify-operation, another thread might come in, interrupting the first one, and starts writing whatever data he has. Now both threads are working at the 'same' time on the data, corrupting the data.
for i as integer = 1 to 10 ' a context switch to any other thread might occur anytime
array.append thread1Data(i)
next
for i as integer = 1 to 10 ' a context switch to any other thread might occur anytime
array.append thread2Data(i)
next
Thread1's i is 5. The data is half appended. Thread2 becomes active, starts appending data to the same array. Now the data is already corrupted. You end up with 20 items in your array which are in a total unpredictable order since you never know when context switches occur.
If the array is protected, any thread who wants to modify the array will say "knock knock, someone already in here?". And if there's another thread busy on the array, he will just wait until the other thread has finished it's work on the array.
Thanks for your answer.
With my way of not using CriticalSections, I'd solve the problem above by suspending one thread from the other, or similar approaches. This is almost identical than using CriticalSections, because one thread would be stopped and resumed when the other has finished adding the data.
The only benefit I see using CriticalSections is that the thread is suspended automatically (by marking a resource as locked) rather than manually (under certain conditions, suspend one thread from code). Any benefit I'm missing?
Regards,
Arnaud
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Jim McKay
2013-05-14 15:40:02 UTC
Permalink
Post by Marnaud
Post by d***@public.gmane.org
Thread1's i is 5. The data is half appended. Thread2 becomes active, starts appending data to the same array. Now the data is already corrupted. You end up with 20 items in your array which are in a total unpredictable order since you never know when context switches occur.
If the array is protected, any thread who wants to modify the array will say "knock knock, someone already in here?". And if there's another thread busy on the array, he will just wait until the other thread has finished it's work on the array.
Thanks for your answer.
With my way of not using CriticalSections, I'd solve the problem above by suspending one thread from the other, or similar approaches. This is almost identical than using CriticalSections, because one thread would be stopped and resumed when the other has finished adding the data.
The only benefit I see using CriticalSections is that the thread is suspended automatically (by marking a resource as locked) rather than manually (under certain conditions, suspend one thread from code). Any benefit I'm missing?
Regards,
Arnaud
I'm learning a lot from this thread! It seems that the CriticalSection would have the benefit of allowing the separate threads to do other work freely until they try to access an object that is currently accessed by another thread.

For instance a buffer array where one thread is storing results in an array and another thread is checking the array for content to process and then clearing it when done. With a criticalSection both threads can operate freely until they both hit the code that accesses the array, then one would wait until the other moves along, and then continue.

Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem? Just wondering if there's much overhead, or is it negligible.

Also, what about the main thread? Will it also pause?

Thanks,
Jim McKay
piDog.com



_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Marnaud
2013-05-14 15:55:21 UTC
Permalink
Post by Jim McKay
I'm learning a lot from this thread!
And me, I'm learning a lot from this CriticalSection! ;-)
Post by Jim McKay
It seems that the CriticalSection would have the benefit of allowing the separate threads to do other work freely until they try to access an object that is currently accessed by another thread.
This would avoid the need to make conditional calls to suspend the thread. Interesting.
Post by Jim McKay
For instance a buffer array where one thread is storing results in an array and another thread is checking the array for content to process and then clearing it when done. With a criticalSection both threads can operate freely until they both hit the code that accesses the array, then one would wait until the other moves along, and then continue.
Up to now, I've been fine with logical tests to figure out if one thread should be suspended. Is it worth using the CriticalSection?
Post by Jim McKay
Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem? Just wondering if there's much overhead, or is it negligible.
Also, what about the main thread? Will it also pause?
Two good questions.
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Charles Yeomans
2013-05-14 16:07:10 UTC
Permalink
Post by Marnaud
Post by Jim McKay
I'm learning a lot from this thread!
And me, I'm learning a lot from this CriticalSection! ;-)
Post by Jim McKay
It seems that the CriticalSection would have the benefit of allowing the separate threads to do other work freely until they try to access an object that is currently accessed by another thread.
This would avoid the need to make conditional calls to suspend the thread. Interesting.
Post by Jim McKay
For instance a buffer array where one thread is storing results in an array and another thread is checking the array for content to process and then clearing it when done. With a criticalSection both threads can operate freely until they both hit the code that accesses the array, then one would wait until the other moves along, and then continue.
Up to now, I've been fine with logical tests to figure out if one thread should be suspended. Is it worth using the CriticalSection?
Yes.
Post by Marnaud
Post by Jim McKay
Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem? Just wondering if there's much overhead, or is it negligible.
Also, what about the main thread? Will it also pause?
Two good questions.
The main thread will block.


Charles Yeomans
Charles Yeomans
2013-05-14 16:06:06 UTC
Permalink
Post by Jim McKay
Post by Marnaud
Post by d***@public.gmane.org
Thread1's i is 5. The data is half appended. Thread2 becomes active, starts appending data to the same array. Now the data is already corrupted. You end up with 20 items in your array which are in a total unpredictable order since you never know when context switches occur.
If the array is protected, any thread who wants to modify the array will say "knock knock, someone already in here?". And if there's another thread busy on the array, he will just wait until the other thread has finished it's work on the array.
Thanks for your answer.
With my way of not using CriticalSections, I'd solve the problem above by suspending one thread from the other, or similar approaches. This is almost identical than using CriticalSections, because one thread would be stopped and resumed when the other has finished adding the data.
The only benefit I see using CriticalSections is that the thread is suspended automatically (by marking a resource as locked) rather than manually (under certain conditions, suspend one thread from code). Any benefit I'm missing?
Regards,
Arnaud
I'm learning a lot from this thread! It seems that the CriticalSection would have the benefit of allowing the separate threads to do other work freely until they try to access an object that is currently accessed by another thread.
For instance a buffer array where one thread is storing results in an array and another thread is checking the array for content to process and then clearing it when done. With a criticalSection both threads can operate freely until they both hit the code that accesses the array, then one would wait until the other moves along, and then continue.
Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem? Just wondering if there's much overhead, or is it negligible.
Also, what about the main thread? Will it also pause?
I'd say it is recommend to use a CriticalSection anytime a mutable resource could be accessed from multiple threads. A file is an example of a mutable resource; so is an Rb array.

As for overhead -- locks are the bottleneck of concurrent programming. Once you've started to share resources between threads, you've committed to some overhead. The use of a CriticalSection is usually cheaper than the time spent trying to debug bugs in threaded code.


Charles Yeomans
Charles Yeomans
2013-05-14 16:13:01 UTC
Permalink
Post by Jim McKay
Post by Marnaud
Post by d***@public.gmane.org
Thread1's i is 5. The data is half appended. Thread2 becomes active, starts appending data to the same array. Now the data is already corrupted. You end up with 20 items in your array which are in a total unpredictable order since you never know when context switches occur.
If the array is protected, any thread who wants to modify the array will say "knock knock, someone already in here?". And if there's another thread busy on the array, he will just wait until the other thread has finished it's work on the array.
Thanks for your answer.
With my way of not using CriticalSections, I'd solve the problem above by suspending one thread from the other, or similar approaches. This is almost identical than using CriticalSections, because one thread would be stopped and resumed when the other has finished adding the data.
The only benefit I see using CriticalSections is that the thread is suspended automatically (by marking a resource as locked) rather than manually (under certain conditions, suspend one thread from code). Any benefit I'm missing?
Regards,
Arnaud
I'm learning a lot from this thread! It seems that the CriticalSection would have the benefit of allowing the separate threads to do other work freely until they try to access an object that is currently accessed by another thread.
For instance a buffer array where one thread is storing results in an array and another thread is checking the array for content to process and then clearing it when done. With a criticalSection both threads can operate freely until they both hit the code that accesses the array, then one would wait until the other moves along, and then continue.
Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem? Just wondering if there's much overhead, or is it negligible.
Also, what about the main thread? Will it also pause?
I'd say it is recommend to use a CriticalSection anytime a mutable resource could be accessed from multiple threads. A file is an example of a mutable resource; so is an Rb array.

As for overhead -- locks are the bottleneck of concurrent programming. Once you've started to share resources between threads, you've committed to some overhead. The use of a CriticalSection is usually cheaper than the time spent trying to debug bugs in threaded code.


Charles Yeomans
Jim McKay
2013-05-14 16:27:35 UTC
Permalink
Post by Charles Yeomans
As for overhead -- locks are the bottleneck of concurrent programming. Once you've started to share resources between threads, you've committed to some overhead. The use of a CriticalSection is usually cheaper than the time spent trying to debug bugs in threaded code.
I'd guess the overhead trumps the possibility of corrupted files or data.. I'm gonna go review some code ;-)
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
d***@public.gmane.org
2013-05-14 17:43:08 UTC
Permalink
Post by Jim McKay
Is it recommended to use a CriticalSection anytime a resource *could* be accessed from another thread? Or only when you know it will be and will cause a problem?
It would be ok if one thread only reads and one only writes (if the reading thread can deal with incomplete data). But if both are modifying the same data it's unlikely that all goes well (not *entirely* impossible, depends on what the code exactly does).
Post by Jim McKay
Just wondering if there's much overhead, or is it negligible.
Depends on how many threads might race for the same resource, and how long a thread needs to modify the resource. For my logfile, a collision happens maybe all 10 minutes, not worth mentioning at all.
You could count the collisions to get an idea how often a thread waits for another.
Post by Jim McKay
Also, what about the main thread? Will it also pause?
Yes.


Kind regards
Christian
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>
Continue reading on narkive:
Loading...