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