Hi! I'm Davide and I have just started doing some jobs in VREP.
I would like to have some explanation about users's tool provided in order to achieve synchronization in threated applications.Mainly i do not understand the difference between " sim.setThreadAutomaticSwitch + sim.switchThread" and "sim.setThreadIsFree" given that the goal is basically ensure some blocking operations .
Thanks,
Davide
Clarification about "Thread related functionality"
-
- Posts: 5
- Joined: 28 May 2018, 08:52
Re: Clarification about "Thread related functionality"
Hello Davide,
a threaded child script is running more like a coroutine than a thraditional thread:
By default, when a threaded child script is launched, it will execute about 2ms. Then V-REP will interrupt or pause it, and only resume it in next simulation step (i.e. when the simulation time has become t=t+dt). It will resume for about 2ms, and be interrupted again. And resume again in next simulation step, and so on, and so forth.
Following example illustrates this:
In above example, the inner loop gets executed many times for each simulation step. Interruption happens automatically,
Now just add sim.switchThread() as in following example:
In above example, the inner loop gets executed almost exactly once for each simulation step. You are deciding when to interrupt. But the automatic interruption can still occur.
Now modify above example with a delay, so that it spends a little bit more time for each inner loop pass, to better visualize that the automatic switch is still happening:
Now you clearly see that you are still not fully in control about the switching moment. In order to be able to perfectly synchronize your threaded script, you need to disable automatic thread switching, as in following example:
Cheers
a threaded child script is running more like a coroutine than a thraditional thread:
By default, when a threaded child script is launched, it will execute about 2ms. Then V-REP will interrupt or pause it, and only resume it in next simulation step (i.e. when the simulation time has become t=t+dt). It will resume for about 2ms, and be interrupted again. And resume again in next simulation step, and so on, and so forth.
Following example illustrates this:
Code: Select all
function sysCall_threadmain()
local lastSimulationTime=sim.getSimulationTime()
local simulationStep=sim.getSimulationTimeStep()
while true do
local cnt=0
-- Inner loop:
while sim.getSimulationTime()==lastSimulationTime do
cnt=cnt+1
end
printf('Inner loop executed %i times for one simulation step.',cnt)
local dt=sim.getSimulationTime()-lastSimulationTime
printf('Thread was interrupted %i times since last simulation step.',math.floor((dt/simulationStep)+0.5))
lastSimulationTime=sim.getSimulationTime()
end
end
Now just add sim.switchThread() as in following example:
Code: Select all
function sysCall_threadmain()
local lastSimulationTime=sim.getSimulationTime()
local simulationStep=sim.getSimulationTimeStep()
while true do
local cnt=0
-- Inner loop:
while sim.getSimulationTime()==lastSimulationTime do
cnt=cnt+1
sim.switchThread()
end
printf('Inner loop executed %i times for one simulation step.',cnt)
local dt=sim.getSimulationTime()-lastSimulationTime
printf('Thread was interrupted %i times since last simulation step.',math.floor((dt/simulationStep)+0.5))
lastSimulationTime=sim.getSimulationTime()
end
end
Now modify above example with a delay, so that it spends a little bit more time for each inner loop pass, to better visualize that the automatic switch is still happening:
Code: Select all
function sysCall_threadmain()
local lastSimulationTime=sim.getSimulationTime()
local simulationStep=sim.getSimulationTimeStep()
while true do
local cnt=0
-- Inner loop:
while sim.getSimulationTime()==lastSimulationTime do
for j=1,100000,1 do end -- delay loop
cnt=cnt+1
sim.switchThread()
end
printf('Inner loop executed %i times for one simulation step.',cnt)
local dt=sim.getSimulationTime()-lastSimulationTime
printf('Thread was interrupted %i times since last simulation step.',math.floor((dt/simulationStep)+0.5))
lastSimulationTime=sim.getSimulationTime()
end
end
Code: Select all
function sysCall_threadmain()
sim.setThreadAutomaticSwitch(false)
local lastSimulationTime=sim.getSimulationTime()
local simulationStep=sim.getSimulationTimeStep()
while true do
local cnt=0
-- Inner loop:
while sim.getSimulationTime()==lastSimulationTime do
for j=1,100000,1 do end -- delay loop
cnt=cnt+1
sim.switchThread()
end
printf('Inner loop executed %i times for one simulation step.',cnt)
local dt=sim.getSimulationTime()-lastSimulationTime
printf('Thread was interrupted %i times since last simulation step.',math.floor((dt/simulationStep)+0.5))
lastSimulationTime=sim.getSimulationTime()
end
end
-
- Posts: 5
- Joined: 28 May 2018, 08:52
Re: Clarification about "Thread related functionality"
Thanks for the example, now things seems to be much clear. Just another question, what about " simSetThreadFree"?
In my mind, these bottom situations are the same:
Cheers
In my mind, these bottom situations are the same:
Code: Select all
-- EXAMPLE with AutomaticSwitch
function sysCall_threadmain()
while true do
sim.setThreadAutomaticSwitch(true)
-- some non ordinary routine here
sim.setThreadAutomaticSwitch(false)
-- some routines that need to be blocked
sim.setThreadAutomaticSwitch(true) -- end of the blocking part OR sim.switchThread()
end
Code: Select all
-- EXAMPLE with setThreadIsFree
function sysCall_threadmain()
while true do
-- some non ordinary routine here
sim.setThreadIsFree(false) -- start of the blocking part
-- some routines that need to be blocked
sim.setThreadIsFree(true) --end of the blocking part
end
Re: Clarification about "Thread related functionality"
sim.setThreadIsFree is kind of dangerous to use: it basically turns your coroutine into a real thread: in that case, you are not allowed to call the V-REP API, otherwise you risk collisions and crashes. I highly recommend not to use it.
Cheers
Cheers