Hi everyone,
I am working on image acquisition for a camera. The main task is to continuously taking images and put them in sharred memory for other programs to grab. The main function is just a simple while loop which calls an external C function (camera API) to take an image, then put the image and its timestamp in the pre-attached shared arrays.
function work(camera::Camera, remcam::RemoteCamera)
# set acquisition mode
set_acquisitionmode(camera, "Continuous")
# begin acquisition
@info "start acquisition loop "
start(camera)
counter = 0
while true
#get image
img =
try
SpinnakerCameras.next_image(camera, 1)
catch ex
@warn "image corrupted"
if (!isa(ex, SpinnakerCameras.CallError) ||
ex.code != SpinnakerCameras.SPINNAKER_ERR_TIMEOUT)
rethrow(ex)
end
nothing
end
# check image completeness
if img.incomplete == 1 && img.status != 0
@goto clear_img
end
counter +=1
# get data and timestamp from image handle
ts = img.timestamp
img_data = @view img.data[:,:]
# lock and write information to shared arrays
wrlock(remcam.img,1) do
copyto!(remcam.img, img)
end
wrlock(remcam.imgTime,1) do
remcam.imgTime[1] = ts
end
@label clear_img
finalize(img)
end
nothing
end
When it runs locally, it works perfectly fine. However, when I use @spawn
when calling the function and fetch the Future
fetch(@spawn SpinnakerCameras.work(camera,remcam))
it produces an error message
cannot serialize a running Task
error(s::String) at error.jl:33
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, t::Task) at Serialization.jl:445
serialize_any(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:657
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:636
serialize_any(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:657
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:636
serialize_any(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:657
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:636
serialize_global_from_main(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, sym::Symbol) at clusterserialize.jl:155
#6 at clusterserialize.jl:101 [inlined]
foreach at abstractarray.jl:2141 [inlined]
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, t::Core.TypeName) at clusterserialize.jl:101
serialize_type_data(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, t::DataType) at Serialization.jl:539
serialize_type(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, t::DataType, ref::Bool) at Serialization.jl:583
serialize_any(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:653
serialize(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, x::Any) at Serialization.jl:636
serialize_msg(s::Distributed.ClusterSerializer{Sockets.TCPSocket}, o::Distributed.CallMsg{:call}) at messages.jl:78
#invokelatest#2 at essentials.jl:708 [inlined]
invokelatest at essentials.jl:706 [inlined]
send_msg_(w::Distributed.Worker, header::Distributed.MsgHeader, msg::Distributed.CallMsg{:call}, now::Bool) at messages.jl:174
send_msg at messages.jl:122 [inlined]
#remotecall#140 at remotecall.jl:365 [inlined]
remotecall(::Function, ::Distributed.Worker) at remotecall.jl:364
remotecall(::Function, ::Int64; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) at remotecall.jl:376
remotecall at remotecall.jl:376 [inlined]
spawnat(p::Int64, thunk::Function) at macros.jl:15
spawn_somewhere(thunk::Function) at macros.jl:17
top-level scope at macros.jl:50
eval at boot.jl:360 [inlined]
I want to run this routine on a different worker process because I want the camera to work like a server which takes commands from RELP and operates in the background. Or is it better to run it locally and use another RELP to communicate with the camera as a client instead?
Appreciate any help!
Best,
Sitthichat