I am implementing a J1939 socket handler on top of Boost::ASIO and canary. My previous application had a socket to listen for devices and the each device discovered would also have a socket. Each socket would use the same interface (In this case can0). From my understanding of SocketCan and J1939 this is the correct approach. As each socket can have filters applied to only get messages from the device its listening for.
In my current application I have tested async_read
on two sockets with two threads executing io_context.run()
. From the logs this seems to be perfectly fine. I am guessing that this is because the kernel checks against the filters on each socket before passing the data on. However with async_write
I am a lot more uncertain about thread safety.
Given that all the sockets have the same interface (can0) would the sockets need to share a strand? Or is a strand in each socket handler enough? Or is there is there some synchronization in the kernel that means writing to the CAN-bus is thread safe.
CodePudding user response:
Yes there is synchronization in the kernel. The same happens for example with TCP sockets. They also share a single network interface (like eth0). The linux network subsystem makes sure, that different sockets (used by different threads or even processes) can share one interface without colliding. You only need synchronization if you access one socket from several threads simultaneously.