Page 1 of 1
Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 5:24 pm
by swhite
Hi
I have been trying to pass a Map to a thread using CreateThread(@MyThread(),myMap()) but the map is always empty. The compiler does not complain so I am assuming it should work. Can anyone confirm that passing a Map to a thread is or is not possible?
Code: Select all
Global Ports.comPort()
Procedure myThread(MAP toPorts.COMPort())
...
EndProc
CreateThread(@myThread(),Ports())
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 5:35 pm
by skywalk
You can pass a pointer to CreateThread(). It is far better to pass a pointer to your structured thread. Then act on the state you are in; PAUSE, RESUME, STOP, DO_SOMETHING_SPECIAL.
The maps and arrays can be updated in the called thread procedure.
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 5:44 pm
by swhite
Hi
I tried CreateThread(@myThread(),@Ports()) but the result was the same so are you referring to something different from what I have shown?
Simon
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 5:54 pm
by skywalk
You have to show a code snippet.
My threads come and go, but do not house any data structures.
They act on data structures within the calling procedure.
Search mk-soft and infratec for their excellent thread examples.
This is my thread stucture.
Code: Select all
Structure Thread_INFO ;- Thread_INFO
; thread specific
n.i ; Thread PB number
h.i ; Thread Handle
sig.i ; Semaphore synchronization
mut.i ; Mutex synchronization
cmd.i ; Operation
now.i ; Status
; data msg's
dat.i
nthPt.i
r$ ; Results for gui display.
EndStructure
Global thr1.Thread_INFO
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 6:02 pm
by swhite
Hi
I use threads all the time with structures and they work perfectly. The problem I am trying to solve is whether a map of structures can be passed to a thread. I have an app that monitors a serial port and passes a structure to the thread that captures the data etc. Now the app needs to monitor two serial ports so I need to pass two structures to the thread. So I thought I would use a map of structures but it does not work as expected since the map is empty.
I guess I can always create another structure with pointers to the two serial port structures.
Simon
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 6:27 pm
by chi
Do you have something like this in mind?
Code: Select all
Structure COMPort
id.i
EndStructure
Global NewMap Ports.COMPort()
Procedure myThread(*toPorts.COMPort)
Debug *toPorts\id
*toPorts\id + 2
EndProcedure
Ports("no1")\id = 1
CreateThread(@myThread(), Ports())
Ports("no2")\id = 2
CreateThread(@myThread(), Ports())
Delay(500)
ForEach Ports()
Debug Ports()\id
Next
[/size]
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 6:56 pm
by swhite
Hi Chi
That is close to what I am doing except that the thread must handle both ports. So there is only one thread accessing two ports. So I want myThread to work as shown below.
Code: Select all
Procedure myThread(*toPorts.COMPort)
Debug *toPorts("no1")\id
*toPorts("no1")\id + 2
Debug *toPorts("no2")\id
*toPorts("no2")\id + 2
EndProcedure
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 7:13 pm
by helpy
Put the map inside a structure and pass the structured variable to the thread.
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 7:48 pm
by chi
Code: Select all
Structure COMPort
id.i
EndStructure
Structure _Ports
Map Port.COMPort()
EndStructure
Global Ports._Ports
Procedure myThread(*toPorts._Ports)
ForEach *toPorts\Port()
Debug *toPorts\Port()\id
*toPorts\Port()\id + 2
Next
EndProcedure
Ports\Port("no1")\id = 1
Ports\Port("no2")\id = 2
CreateThread(@myThread(), Ports)
Delay(500)
ForEach Ports\Port()
Debug Ports\Port()\id
Next
[/size]
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 8:42 pm
by swhite
Hi
I just used another structure as shown below and it works. So the bottom line is that you cannot pass a MAP directly to a thread.
Thank-you everyone for your help.
Code: Select all
Structure Ports
*COM1.comPort
*COM2.comPort
EndStructure
Global goPorts.Ports,goPort1.comPort,goPort2.comPort
goPorts\COM1 = @goPort1
goPorts\COM2 = @goPort2
CreateThread(@myThread(),@goPorts)
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Tue Jan 28, 2020 10:02 pm
by skywalk
Now I see what you mean?
I never pass data structures directly to the thread.
But, this code does seem buggy.
Code: Select all
Structure COMPort
id.i
EndStructure
Structure _Ports
Map Port.COMPort(32)
EndStructure
Global NewMap mPort.COMPort(32)
Global Ports._Ports
Procedure myThread(*toPorts._Ports)
ForEach *toPorts\Port()
*toPorts\Port()\id + 2
Next
EndProcedure
Procedure myThread2(Map *mp.COMPort())
Debug "myThread2 MapSize(*mp()) = " + MapSize(*mp())
ForEach *mp()
Debug MapKey(*mp()) + " = " + *mp()\id
*mp()\id = 99
Next
EndProcedure
Debug "--BEFORE Thread--"
Ports\Port("no1")\id = 1
Ports\Port("no2")\id = 2
mPort("no1")\id = 11
mPort("no2")\id = 12
ForEach Ports\Port()
Debug MapKey(Ports\Port()) + " = " + ports\Port()\id
Next
ForEach mPort()
Debug MapKey(mPort()) + " = " + mPort()\id
Next
ResetMap(mPort())
NextMapElement(mPort())
thrn = CreateThread(@myThread(), Ports)
thrn2 = CreateThread(@myThread2(), mPort())
WaitThread(thrn, 500)
WaitThread(thrn2, 500)
Debug "--AFTER Thread--"
ForEach Ports\Port()
Debug MapKey(Ports\Port()) + " = " + ports\Port()\id
Next
ForEach mPort()
Debug MapKey(mPort()) + " = " + mPort()\id
Next
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Wed Jan 29, 2020 11:19 am
by Fred
You can't be pass Map or any other object to a thread, you need to stick to a raw pointer for the thread function. May be the doc is not clear enough about this subject
Re: Can you pass a Map to a Thread using CreateThread()?
Posted: Wed Jan 29, 2020 4:15 pm
by swhite
I did not realize that passing a map was not a pointer but then again I do not know much about the internal structure of maps so thank-you for the clarification and perhaps a mention about MAPs might be helpful in the documentation.
It worked perfectly once I switched to passing a pointer to a structure.
Simon