Thread observation

Just starting out? Need help? Post your questions and find answers here.
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Thread observation

Post by Rinzwind »

Code: Select all

EnableExplicit

Global m_mutex = CreateMutex()
;Global NewList m()
Procedure Inc(show = 0)
  Static NewList m.i()
  Static x
  Protected r
  LockMutex(m_mutex)
  If show
    ForEach m()
      Debug m()
    Next
    UnlockMutex(m_mutex)
    ProcedureReturn
  EndIf  
  
  x +1
  AddElement(m())
  m() = x
  r = x
  UnlockMutex(m_mutex)
 
  ProcedureReturn r
EndProcedure


Procedure Thread1(p)
  Protected i
  For i = 1 To 100
    Inc()
  Next
EndProcedure

Define j
For j = 1 To 10
  CreateThread(@Thread1(), j)
Next

Delay(2000)
inc(#True)
One would think this would run nicely, but it errors out. With compiler option Thread-safe it works. But since this code already makes sure data access is synced, it should work fine? What makes it break?

Heck, even this crashes most of the time, no concurrent access at all:

Code: Select all

EnableExplicit

Procedure Inc()

EndProcedure

Procedure Thread1(p)
  Protected i
  For i = 1 To 100
    Inc()
  Next
EndProcedure

Define j
For j = 1 To 10
  CreateThread(@Thread1(), j)
Next

Delay(2000)
Edit:
Without debugger it seems fine, so conclusion is that you need the threadsafe option when you want to use the debug mode.
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Thread observation

Post by STARGÅTE »

Rinzwind wrote: Sun Apr 18, 2021 8:38 am Without debugger it seems fine, so conclusion is that you need the threadsafe option when you want to use the debug mode.
You need the thread-safe option in any cases when using threads!
And you have to protect your code in any cases when using threads!
Thread-Safe option just means, that the PB compiler uses slightly different internal code for functions like Strings, Debugger, Images ect.
The Thread-Safe option doesn't protect yourself written code.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Thread observation

Post by Rinzwind »

Of course you can write threadsafe code without the compiler setting, as is proven without using debugger.

The manual is also very vague about what the treadsafe option influences. Too vague.

And of course, better safe than sorry, so just enable it. Not knowing what it does exactly.

The second example code did NOTHING at all and still crashed. Which is because the debugger can't handle it (even without breakpoints).

And if indeed, treadsafe option is always needed, then PB compiler should complain when using thread functionality while it is not enabled.
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Thread observation

Post by STARGÅTE »

Rinzwind wrote: Sun Apr 18, 2021 11:37 am Of course you can write threadsafe code without the compiler setting, as is proven without using debugger.
It's not a valid proof, when the code not crashes :wink: . In other situations it could crash.
Also the documentation is clear:
Create thread-safe executable
This tells the compiler to use a special version of certain commands to make them safe to be used in threads. See the Thread library for more information.
This also enables the Debugger to display correct information if threads are used. Without this option, the debugger might output wrong line numbers when threads are involved for example.
PureBasic has a special compiler setting to create thread-safe executables. (/THREAD command-line switch or "create thread-safe executable" in the IDE compiler options). Without this mode, certain functions (and also the string access) are faster, but not safe to use in threads. It is still possible to create threads without this mode but it is not recommended, as even something simple like a local string access can be dangerous and needs to be protected. Enabling this option makes these things save inside threads, but comes at the price of some speed. The decision on whether or not to use threads should therefore done with care, and the threadmode should only be used when there is a real need for it.
Note: Threads need to be used carefully because it is possible that you can have multiple access to shared resources (memory, variables, files, etc) and you need to manually ensure that you do run into trouble because of this. The Mutex functions in this library can be used to synchronize access to such shared resources.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Thread observation

Post by Rinzwind »

I wouldn't call 'certain commands' clear. It's missing ALL details ;) Local (procedure) string access should be tread-safe in any language. Thread-safe only applies to shared/global data.

Side note: sadly ForEach is not thread-safe (I didn't expect much, but wanted it tested). I hoped it would use 'Threaded' pointers and could be used for read-only loops in threads independently from each other (with the infamous thread-safe compiler option on). Nope, have to lock the whole code between a mutex.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Thread observation

Post by skywalk »

I am not understanding the complaint?
Just like EnableExplicit, I believe Threaded should be enabled by default.
Has anyone documented the speed difference without it?
Only the smallest of utilities can run without it, but even then, I wind up adding more features that demand threads.
There are so many coding pitfalls to avoid, why add another by ignoring threads?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Thread observation

Post by STARGÅTE »

I gess you missunderstand this "thread-safe" option of the PB compiler.
The "thread-safe" has nothing to do with your management of shared/global data.
Rinzwind wrote: Sun Apr 18, 2021 2:34 pm Side note: sadly ForEach is not thread-safe (I didn't expect much, but wanted it tested). I hoped it would use 'Threaded' pointers and could be used for read-only loops in threads independently from each other (with the infamous thread-safe compiler option on). Nope, have to lock the whole code between a mutex.
If your LinkedList is a global list, ForEach is indeed not safe in threads. The current element pointer is shared between all threads.
If you use the Threaded-Keyword, you allocate an individual LinkedList for each thread, which is no more shared between threads.
If several threads should use the same LinkedList (ForEach), each single call of a ForEach-Next-Loop needs a locked mutex (of cause the same mutex).
skywalk wrote: Sun Apr 18, 2021 2:48 pm Just like EnableExplicit, I believe Threaded should be enabled by default.
Why? There are several cases, where I want to have a Global variable instead of a Threaded variable. Or what do you mean with "Threaded"?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Thread observation

Post by skywalk »

I meant ThreadSafe compiler option.
Not threaded variables by default!
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Thread observation

Post by Rinzwind »

I just mentioned ForEach, because it should be straight forward to make read operations thread safe by default as is the case in many other languages/libraries. Certainly vastly increases its performance in thread scenarios.
Post Reply