Difference between revisions of "Thread safety in Visual Prolog"

From wiki.visual-prolog.com

(mapM/setM)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
Thread safe:
Thread safe:


* Access to fact variables
* Access facts
* Access to single facts
* Access to determ facts


'''Not''' thread safe:
'''Not''' thread safe:


* Nondeterm facts
* GUI
* GUI
* Streams
* Streams
* odbcConnection/odbcStatement
* odbcConnection/odbcStatement


=== Nondeterm facts ===
=== Facts ===


Read access is thread safe, but only a single thread should update a nondeterm fact.  Reading can be done while update takes place.
See [[Threadsafe facts]].


=== GUI ===
=== GUI ===
Line 34: Line 31:
An <vp>odbcConnection</vp>/<vp>odbcStatement</vp> is not thread safe, but different <vp>odbcConnection</vp>'s/<vp>odbcStatement</vp>'s can be accessed in parallel.
An <vp>odbcConnection</vp>/<vp>odbcStatement</vp> is not thread safe, but different <vp>odbcConnection</vp>'s/<vp>odbcStatement</vp>'s can be accessed in parallel.


=== mapM and setM ===
<vp>mapM</vp> and <vp>setM</vp> each exist in two threadsafe versions.  Here we will just consider the mapM versions (the setM behaves completely similarly).  Most operations on red-black trees are already threadsafe.  The classes mentioned here ensures that updates are "sound": If you set/add/delete something it will in fact be set/added/deleted.
<vp>mapM_redBlack_cas</vp> uses <vp>compareAndSwap</vp> (see also [https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchange InterlockedCompareExchange]).  If two threads are updating the map simultaneously there is a chance that one of the <vp>compareAndSwap</vp> will fail (the swap only takes place if the current tree is the same that this thread updated).  If that happens the operation will be performed once more on what is now the current tree.
<vp>mapM_redBlack_block</vp> uses a <vp>multiThread_native::srwLock</vp> (see also [https://learn.microsoft.com/en-us/windows/win32/sync/slim-reader-writer--srw--locks Slim Reader/Writer (SRW) Locks]) to block threads that tries to update the map while another thread is already updating the thread.
So in case of collisions the <vp>mapM_redBlack_cas</vp> will use extra resources (CPU, memory allocations, etc) whereas the <vp>mapM_redBlack_block</vp> will block a thread instead.  If there are few collision then the <vp>_cas</vp> version will not waste much time and no threads will be blocked and involve the operating systems thread scheduling mechanism.  If there are many collisions then the <vp>_block</vp> version will go easy on CPU, memory and instead involve the task scheduling mechanism.
Notice that if you have really many collisions then you have a problem in any case, because then your threads will either spend resources or wait all the time. In the first case there will be a large load on you computer, in the second case the benefit you hoped for using many threads will disappear in waiting.
[[Category:Multi-threading]]
[[Category:GUI]]
[[Category:GUI]]
[[Category:ODBC]]
[[Category:ODBC]]
[[category:Multi-threading]]

Latest revision as of 10:45, 5 November 2024

Thread safe:

  • Access facts

Not thread safe:

  • GUI
  • Streams
  • odbcConnection/odbcStatement

Facts

See Threadsafe facts.

GUI

Windows GUI is not thread safe, only the thread that runs the message pump of a window should accees that window. In Visual Prolog all windows (except modal dialogs) belong to the thread that have executed the vpi::init call.

Synchronization back to the GUI thread can be done using window::postAction, because the posted action will be executed by the GUI thread.

Modal dialogs run their own message pump and they are therefore owned by the thread that displays them.

Streams

Streams are in general not thread safe, but specific streams can be.

From Visual Prolog 7.4 the thread on messageControls are thread safe. In a GUI application stdio will thus be thread safe while it is redirected to a messageControl/messageForm, but if it is redirected to some other stream it will "inherit" the thread safety from that stream.

ODBC

An odbcConnection/odbcStatement is not thread safe, but different odbcConnection's/odbcStatement's can be accessed in parallel.

mapM and setM

mapM and setM each exist in two threadsafe versions. Here we will just consider the mapM versions (the setM behaves completely similarly). Most operations on red-black trees are already threadsafe. The classes mentioned here ensures that updates are "sound": If you set/add/delete something it will in fact be set/added/deleted.

mapM_redBlack_cas uses compareAndSwap (see also InterlockedCompareExchange). If two threads are updating the map simultaneously there is a chance that one of the compareAndSwap will fail (the swap only takes place if the current tree is the same that this thread updated). If that happens the operation will be performed once more on what is now the current tree.

mapM_redBlack_block uses a multiThread_native::srwLock (see also Slim Reader/Writer (SRW) Locks) to block threads that tries to update the map while another thread is already updating the thread.

So in case of collisions the mapM_redBlack_cas will use extra resources (CPU, memory allocations, etc) whereas the mapM_redBlack_block will block a thread instead. If there are few collision then the _cas version will not waste much time and no threads will be blocked and involve the operating systems thread scheduling mechanism. If there are many collisions then the _block version will go easy on CPU, memory and instead involve the task scheduling mechanism.

Notice that if you have really many collisions then you have a problem in any case, because then your threads will either spend resources or wait all the time. In the first case there will be a large load on you computer, in the second case the benefit you hoped for using many threads will disappear in waiting.