Hi,
Is it a non-blocking alternative to recvfrom() ?
My application consist of two threads, where one of them is listening on a socket for incoming packets. The other thread then sends a signal to this thread after x seconds to tell it to return. This is done by using a Channel. But, it seems that recvfrom is blocking so that it don’t see that a signal is received on the channel… Does anyone have any suggestions to how I can solve this?
Timer on the waiting thread? No need for inter-thread communication here.
No I don’t use a Timer here. Just two threads, where one of them need to tell the other to stop. But it will not see this stop message, because recvfrom is blocking…
Yes, I got that. I was suggesting to use a Timer on the thread that’s waiting in recvfrom instead of using a Channel for that. Using a Channel means you have to actively check it, a Timer will interrupt you.
I want my main thread be the one that tells the second thread (which has the recvfrom) to quit. So I don’t want my second thread to tell itself when to quit…
Well, as far as I know, there is no nonblocking recvfrom (assuming you’re talking about Sockets.recvfrom). There’s also no good way to interrupt a running async task, which is why I suggested using a Timer to periodically interrupt the blocking behavior, then check the Channel for whether or not the thread should terminate or not, then relaunch a Timer and block again.
recvfrom is also written in Julia, you could roll your own
https://github.com/JuliaLang/julia/blob/master/stdlib/Sockets/src/Sockets.jl#L331-L365
I tried implementing a MWE now, and to my surprise this works fine. So after 2 seconds, the signal is sent, and the thread successfully quits… But, why does this work? I thought recvfrom was a blocking call?
using Sockets
function recv_data()
insock = UDPSocket()
from = Sockets.InetAddr(ip"127.0.0.1", 3000)
bind(insock, from.host, from.port)
while !(isready(running) && fetch(running) isa Stop)
from, data = recvfrom(insock)
end
close(insock)
return
end
struct Stop end
running = Channel{Stop}(1)
t1 = @Threads.spawn recv_data()
sleep(2)
put!(running, Stop())
The docs say it blocks
Read a UDP packet from the specified socket, and return the bytes received. This call blocks.
Yes, it does. But then I thought in MWE that recv_data() would not exit as it does, because in the while-loop the recvfrom will block… But it do exit successfully… Why??
Are you sure this is working? It doesn’t appear it is to me:
using Sockets
function recv_data()
insock = UDPSocket()
from = Sockets.InetAddr(ip"127.0.0.1", 3000)
bind(insock, from.host, from.port)
while !(isready(running) && fetch(running) isa Stop)
println("listening...")
from, data = recvfrom(insock)
end
println("done.")
close(insock)
return
end
struct Stop end
running = Channel{Stop}(1)
t1 = @Threads.spawn recv_data()
sleep(2)
put!(running, Stop())
sleep(2)
@show istaskdone(t1)
Outputs:
listening...
istaskdone(t1) = false
Which indicates that the recvfrom call is blocking t1 from exiting.