I'm actually making my first small steps with threads in PB, only for opening new network connections. I found a lot of helpful postings in the board and hopefully learned a lot, but just want to be sure to make everything right. So I hope, that the thread experts have a look on my shortened code and tell me of errors.
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_Thread = 0
CompilerError "compile as thread safe is needed!"
CompilerEndIf
Structure mythreadstruct
device.u
connid.i
name.s
port.l
timeout.l
EndStructure
Structure mydevices
name.s
connected.u
connid.i
*mystart.mythreadstruct
EndStructure
Global Dim devices.mydevices(10)
Enumeration #PB_Event_FirstCustomValue
#ConnectThread
EndEnumeration
Procedure startup()
Protected dev.u
For dev = 1 To 10
devices(dev)\mystart = AllocateStructure(mythreadstruct)
devices(dev)\mystart\device = dev
devices(dev)\mystart\name = "192.168.178."+Str(100+dev)
devices(dev)\mystart\port = 5577 ;20007
devices(dev)\mystart\timeout = 10000
Next dev
EndProcedure
Procedure connect_thread(*start.mythreadstruct)
Protected ret.i
ret = OpenNetworkConnection(*start\name,*start\port,#PB_Network_TCP | #PB_Network_IPv4,*start\timeout)
*start\connid = ret
PostEvent(#ConnectThread,1,*start\device)
EndProcedure
Procedure event_thread(dev.u)
If devices(dev)\mystart\connid <> 0
devices(dev)\connid = devices(dev)\mystart\connid
Debug "Connected "+Str(dev)
devices(dev)\connected = 2
Else
devices(dev)\connid = 0
Debug "Not Connected "+Str(dev)
devices(dev)\connected = 0
EndIf
EndProcedure
Procedure job_queue(dev.u)
;......
EndProcedure
Procedure main()
Protected dev.u,sysend.u,event.i
;.....
startup()
OpenWindow(1,10,10,200,100,"Thread Testing",#PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
InitNetwork()
Repeat
event = WaitWindowEvent(50)
If event
Select event
Case #PB_Event_CloseWindow
sysend = 1
Case #ConnectThread
event_thread(EventGadget())
EndSelect
Else
For dev = 1 To 10
If devices(dev)\connected = 0
Debug "Start Connect "+Str(dev)
devices(dev)\connected = 1
CreateThread(@connect_thread(),devices(dev)\mystart)
ElseIf devices(dev)\connected = 2
job_queue(dev)
EndIf
Next dev
EndIf
Until sysend
CloseWindow(1)
EndProcedure
main()
-Am i right, that I don't need any mutex or semaphore, because I simply give a pointer to a structure to the thread, and this structure is only accessed from thread and after my event of ended thread?
-Is OpenNetworkConnection thread safe to be used multiple at the same time or should this be only used one after one? My program seems to work, network receive and send is not done in a thread.
-Would it be better, to have every thread open forever and only send a "start reconnect" to a waiting thread, or is it safe or/and better to use short living threads only for one reconnect and let them die after? Thinking of memory leaks etc....
-Using "protected" vars in the thread procedure is enough, or must this vars be "threaded"?
Explanation:
This program in full version is used to control some devices, that are connected to the computer through RS232 or network. The devices normally are getting connected on program startup and then the connection is hold open with status requests every minute or by doing real actions on the devices.
On serial-cabled and network-cabled devices there is no problem in opening and holding the connection, but on Wifi the devices don't switch fast enough between multiple access points, so the connection gets lost sometimes and needs to get reconnected.
For the real actions with the connected devices until now I don't needed threads, the sent and received data is not so time critical, that it can't be solved in one working queue, one device after the other, as there are <= 10 devices.
But the problem is the reconnect on Wifi, sometimes it is fast, but sometimes it needs 5-10 seconds to find a device on an new access point, or sometimes a device simply is offline and the timeout of OpenNetworkConnection is reached. This timeout of 10 seconds is too critical for handling from the queue of the other connected devices, and really short timeouts of 250ms to often don't reach the devices...
In case anyone is interested: program is used to manage payment on credit/debit card terminals via zvt.
Greetings, Hoerbie