Reading sockets asynchronously

I’m using readavailable() within a loop to read messages from a tcp socket as they come in.
Is there a version that doesn’t require a loop ? i.e. something that will call a function asynchronously with the incoming message as and when its received ?

readavailable is pretty much the only API that does not do that (reading asynchronously). Almost any other read function would do just that, resuming the Task at exactly the point it paused and calling the next function

Can you give an example?

Suppose I have function f(message),
and 10 mesaages arrive on the socket almost simultaneously.

Can you give and example of a function that would call f() for each message simultaneously.

No, CPU cores can’t do things (like receive messages or call functions) simultaneously, due to physics

1 Like

See the manual here? In that example replace println with your f(message) .

What Jameson is getting at is that you don’t (in any language) actually write a program that reads messages simultaneously, what you do is read a message one at a time and defer the processing of that message to be done either now or later (concurrent but not simultaneous), whenever the CPU has idle cycles. So what you would do is something like this:

@sync while !eof(sock)
    msg = read_message(sock)
    @async process_message(msg)
end

Here read_message is a function that reads a single message from the socket and process_message is a function that takes a message and does something in response. The @async annotation means that the processing of one message can be done concurrently with the processing of other messages. This means that the processing continues until it reaches a blocking operation and then the scheduler looks at what has become unblocked and continues with that. If you want to (potentially) use threads rather than just non-blocking I/O, then you can replace @async with Threads.@spawn.

5 Likes

Thanks so much Stefan. Threads.@spawn works really well :slight_smile:

related question…

Does the Threads.@threads loop macro have an equivalent for broadcasting ?
Would it be possible to speed up something like exp.( 1:1E7 ) by making it multi-threaded ?

I found broadcast is already faster than the simple multi-threaded loop below

n    = 10_000_000 
Xin  = 1:n
Xout = zeros(n)

Threads.@threads for i = 1:n
    Xout[i] = exp( Xin[i] )
end