What are Critical Sections
They are useful, when you do much memory access.. When you (for example) change a string from multiple processes, your program will crash when you dont use it.
How it works
- In the Enter-procedure every thread receives an unique number, this is guaranteed by the XADD command, which reads and modifies the variable in one call.
- Then the Thread waits, until its his turn
- When the Thread finished, we increase the current Thread-Index, so that the next threads enters the section
Code: Select all
;-
;- PureFan's Critical Sections *SPECIAL*
;-
;- Posted in: English PureBasic Board
;- Date: 28.04.05
;-
Structure Pure_CS
In.l
Out.l
EndStructure
Procedure Pure_InitCS(*PCS.Pure_CS)
*PCS\In=0
*PCS\Out=0
EndProcedure
Procedure Pure_EnterCS(*PCS.Pure_CS)
!POP Edi
!PUSH Edi
!XOR Esi,Esi
!INC Esi
!XADD [Edi],Esi
!.loop:
!PUSH dword 1
!CALL _Sleep@4
!CMP [Edi+4],Esi
!JNE .loop
EndProcedure
Procedure Pure_LeaveCS(*PCS.Pure_CS)
!POP Edi
!PUSH Edi
!INC dword[Edi+4]
EndProcedure
;/
;/ Example for PureFan's Critical Sections
;/
Global SichereStrings.Pure_CS
Pure_InitCS(SichereStrings)
Global GlobalerString.s
Procedure String_Thread(Parameter)
Repeat
Pure_EnterCS(SichereStrings)
lokaler_string.s=GlobalerString+"hallo"
GlobalerString.s=Right(lokaler_string.s,100)
Pure_LeaveCS(SichereStrings)
ForEver
EndProcedure
For I=1 To 10
CreateThread(@String_Thread(),I)
Next I
Repeat
Pure_EnterCS(SichereStrings)
lokaler_string.s=GlobalerString+"hallo"
GlobalerString.s=Right(lokaler_string.s,100)
Pure_LeaveCS(SichereStrings)
ForEver
EDIT: Just published another way to do this in the german forum.. here it is!
Advantage:
* Works also with Multiprocessor-Systems
* You can kill threads with KillThread()/TerminateThread_(), when the commands are inside a CriticalSection! The first code would make problems in some cases!
Code: Select all
;-
;- PureFan's Critical Sections *SPECIAL*
;-
;- Posted in: English PureBasic Board
;- Date: 30.04.05
;-
Structure Pure_CS
Cnt.l
EndStructure
Procedure Pure_InitCS(*PCS.Pure_CS)
*PCS\Cnt=0
EndProcedure
Procedure Pure_EnterCS(*PCS.Pure_CS)
!POP Edi
!PUSH Edi
!.loop:
!PUSH dword 1
!CALL _Sleep@4
!MOV Esi,1
!XCHG [Edi],Esi
!CMP Esi,0
!JNE .loop
EndProcedure
Procedure Pure_LeaveCS(*PCS.Pure_CS)
!POP Edi
!PUSH Edi
!MOV dword [Edi],0
EndProcedure
;/
;/ Example for PureFan's Critical Sections
;/
Global SichereStrings.Pure_CS
Pure_InitCS(SichereStrings)
Global GlobalerString.s
Procedure String_Thread(Parameter)
Repeat
Pure_EnterCS(SichereStrings)
lokaler_string.s=GlobalerString+"hallo"
GlobalerString.s=Right(lokaler_string.s,100)
Pure_LeaveCS(SichereStrings)
ForEver
EndProcedure
For I=1 To 10
CreateThread(@String_Thread(),I)
Next I
Repeat
Pure_EnterCS(SichereStrings)
lokaler_string.s=GlobalerString+"hallo"
GlobalerString.s=Right(lokaler_string.s,100)
Pure_LeaveCS(SichereStrings)
ForEver
Here also the link to the thread in the german forum: http://forums.purebasic.com/german/viewtopic.php?t=3061