Threads and sharing strings

Just starting out? Need help? Post your questions and find answers here.
cbailey
User
User
Posts: 65
Joined: Sat Jun 04, 2005 4:05 am

Threads and sharing strings

Post by cbailey »

In the chat type program I'm making, I ran into a problem with the user update list. What happens is that, if there's 20 people in chat, then it sends the entire updated user list to everybody (I've thought of only sending updates, but worried of missing a user here and there, and getting out of sync with the server's user list). As this tends to tie up the server, if more than a few connect at the same time in this state, the server freezes up, usually permantly. My guess is that I need to put something into a thread so everything doesn't wait for all the user lists to be sent out. My guess is that it's best to put the send and receive routines in a thread (The ones from Mike/tranquil). I've heard of problems sharing variables between threads. What I'm basically doing is writing in one thread, and only reading in another. As I'm not writing from both threads, would this be thread safe? Or is it safe only if a variable is never even accessed at the same time by two threads?

A related question... I'm guessing the answer is NO, but can you call a procedure from another thread?
User avatar
Derlidio
User
User
Posts: 77
Joined: Fri Feb 27, 2004 9:19 pm
Location: SP - Brazil

Post by Derlidio »

You'll be fine with PB and Threads if you take some precautions when dealing shared data. PB automatically imports functions from system dlls that allow us to accomplish this. The prototype code below shows how:

Code: Select all

 ; This goes at the top of the code. 
Global CS_Object.CRITICAL_SECTION 
InitializeCriticalSection_(@CS_Object) 

; This is used when you need to handle shared data: 

EnterCriticalSection_(@CS_Object) 
   ; Do all shared data calculations or modifications 
   ; inside the Enter/Leave block. No other thread, 
   ; neither the main process will be able to get 
   ; ownership of the CS object until we release it... 
LeaveCricitalSection_(@CS_Object) 

; This goes in the end of the program... 

DeleteCriticalSection_(@CS_Object)

Critical section objects assures mutual exclusion to shared data among threads within a single process. You must create one or more critical section structures (deppending on the way you expect to deal with the shared data you have), initialize them and call the appropriated enter/leave functions before accessing the shared resources.

You can also assure mutual exclusion to shared data among different processes (2 different applications running at the same time) by using Mutex objects. The calls are quite the same, but with different names.

Code: Select all

Global Handle.l 
Handle = CreateMutex_(*Null, 0, "MutexName") 
WaitForSingleObject_(Handle) 
ReleaseMutex_(Handle) 
CloseHandle_(Handle)
If I can give you a piece of advide, surround "any" string variable creation/modification with a critical section block if you decide to go with threads. PB string heap is shared between the main process and its threads, so one string allocation can overlap another if they are made at the same time (I had problems with that when running multiple threads in machines with more than 1 processor).

About the other question... yes, you can call any procedure in your code from a thread ;).

hope this helps...

-PJoe
Derlidio Siqueira
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Would this be a alternative to critical sections?

Code: Select all

Global strings_locked.l

Procedure MyThread()

While strings_locked
 Delay(1)
Wend

strings_locked=#True

;Do string stuff here

strings_locked=#False

EndProcedure
Or is there still a chance for race conditions?
User avatar
Derlidio
User
User
Posts: 77
Joined: Fri Feb 27, 2004 9:19 pm
Location: SP - Brazil

Post by Derlidio »

@Rescator: I'm affraid that would not work. Think this situation:

Imagine that you have 4 threads. The 1st one has locked strings by adjusting the strings_locked variable to #True. The other three threads are waiting inside the while-wend loop. When the 1st thread releases the strings_locked variable, more than 1 thread among those that are waiting can actually aquire the right to continue (exit the while-wend), which can lead the application to the disaster scenario.

Critical Sections and Mutex objects are assured to allow ownership for just one thread at a time. Even if 10 threads are waiting for the same object, when the Critical Section is released by the thread that owns it, only one of the waiting threads will actually aquire ownership. The other 9 threads will still waiting.

-PJoe
Derlidio Siqueira
User avatar
aszid
Enthusiast
Enthusiast
Posts: 162
Joined: Thu May 01, 2003 8:38 pm
Location: California, USA
Contact:

Post by aszid »

i have quick question about this, can i use mutex's for arrays or structured arrays as well as normal variables?


*edit*
i realize i could add mutex's to Rescator's idea for arrays and such.. i was just hoping it could work directly.
--Aszid--

Making crazy people sane, starting tomorrow.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Thanks Derlidio.
Any clue what overhead is involved?
Or is it hardly any different than setting a variable?
User avatar
Derlidio
User
User
Posts: 77
Joined: Fri Feb 27, 2004 9:19 pm
Location: SP - Brazil

Post by Derlidio »

According to MSDN documentation, threads consume almost no CPU at all while waiting to gain ownership of a Critical Section or Mutex object. I've used them a lot, and I can say that they are very light and handy. You can find complete reference on Synchronization API at the following address:

http://msdn.microsoft.com/library/defau ... ctions.asp

best wishes...

-PJoe
Derlidio Siqueira
Post Reply