-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multi-threading #70
Comments
I created a multithreaded test and put the test runner inside a script loop.
|
Thanks @blabaere for digging into this. Yeah, it seems really odd. I only started hitting these issues when I had gotten far enough in implementing this library and now it seems it's never not hitting those issues. I know nanomsg said they tried to be thread-safe but there may be a few areas which are not. |
Finally got one example where it would hang forever but let me debug it: |
My bad, it looks like I should add some more sync between the tasks. Here, the sender task is waiting for the end of the test, and the receiver task is waiting for the message. Receiver:
Sender:
|
That blog also uses sleep between bind and connect, in seconds: |
Interesting. I'm wondering if that's the expected procedure for nanomsg, to wait an arbitrary length of time. |
It seems that thread-safety is bought with asynchronous behavior in some Le mar. 9 déc. 2014 22:37, Daniel Fagnan [email protected] a
|
Indeed, using barrier and sleep all over the place to ensure that bind/connect and send/receive correct timings fixes the problem where the test runner would hang forever. A call to nn_term and one more sleep fixes the nanomsg assertion failures. The ugliness can be witnessed here: https://github.com/blabaere/nanomsg.rs/blob/multithreadtest/libnanomsg/src/lib.rs @thehydroimpulse, are we sure we want to show this kind of stuff ? |
@blabaere mmmm, that's a bit unfortunate. |
Got it right this time ! The send/receive order issue I And the bind/connect order requirements can also be dropped. But if you implement that ordering "manually" with barriers the test runs way faster than if you let nanomsg handle the "retry" (wild guess). And guess who looks all nice and tidy now ?https://github.com/blabaere/nanomsg.rs/blob/multithreadtest/libnanomsg/src/lib.rs |
@blabaere Wow, that's awesome! That looks sooo much cleaner. |
To check the thread-safety of individual sockets, one should be shared between several tasks. But of course, Rust will not let you do that since all the read/write operations require a mutable socket. @thehydroimpulse, do you see any problem with |
@blabaere I don't see a huge problem with having |
There's an implied ownership over sockets, however. Less so with nanomsg because they're not as generic as raw tcp. For example, if two threads can read and write on the same socket, you have to have some sort of implied ownership on what operations should be allowed on either thread (otherwise both threads can be reading and they both won't get the full message, it'll be split between the two) |
I didn't think of that message split problem, but it must be fun to debug too. Another potential problem I see now is that nanomsg recycles the int values returned by The choice we have is between :
I'm not in favor of option 2 because I don't want to find myself in the situation mentioned above. And it looks like Rust is all about safety, but that's just my personal opinion here. |
Yeah, I think that's a good approach. I definitely want nanomsg to be as safe as possible and I think not allowing clone would do this. |
I've checked the C code and I'm confident that the library is properly thread-safe. Sockets are created under a global lock, and then interacted with under a private mutex. I think you're right that you cannot have Clone/Copy because you have Drop and this is good. I think the only mistake in the current implementation with regards to multithreading is that you implement the Once the |
Your remark about the Regarding the removal of mutable accesses I think we need to review all socket methods and decide which we should fix. For example I'm not sure I would make |
Consider an example where |
I think that having mutability stated in signatures is not only about multi-threading, or pleasing the compiler or event observable effects in a program but also about communicating intents to developers using a library, and providing some guarantees. In the case of a library depending on nanomsg, let's call it X, borrowing a socket or a mutable socket would convey two different meanings. If I understand the need to support a scenario where a socket is configured on the fly, based on the program execution outcome, including the content of messages exchanged over this socket. This is completely legitimate and I think doing this from multiple threads falls in the shared mutability category which requires special care to handle, and Rust is just making it explicit. As a conclusion, this is technically feasible because thread-safety is guaranteed by nanomsg implementation itself, but I'm not sure this is the right thing to do. @thehydroimpulse any opinion on this ? |
I find your argument compelling because I like the idea but I think digging deeper it's the wrong approach. From the Rust documentation:
I suspect to get the kind of access control you might have to put the |
Another simple (too simple maybe ?) view on that problem is to consider that each of the two threads owns its socket, and if a message received from one socket could requires the application to call |
I can already make the socket shareable between threads in a much simpler way using |
OK for removing all mutability markers then. |
I found this issue while writing multi-threaded code that uses What's the status of this issue? Are the maintainers still ok to drop mutability markers but simply didn't get around to do it? |
I'm still totally OK with accepting a PR that would remove the mutability markers. |
I haven't been able to dig down into it but I want to figure out a way we can get this library to be multi-threaded. As far as I can tell, we aren't using threads/tasks at all in the tests anymore. Nanomsg in theory should be thread-safe (and that was one of the original goals versus something like ZeroMQ where it was strictly thread-unsafe.
The text was updated successfully, but these errors were encountered: