-
Notifications
You must be signed in to change notification settings - Fork 422
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
Exception when using parameterclient while having node spinning in other thread #206
Comments
The spin family of functions which take a node as an argument are not thread safe or reentrant. Since you call https://github.com/firesurfer/Segfault_demo/blob/master/src/test.cpp#L30 I'm not surprised that you get the error, since both functions first add the node to an executor, spin, and then remove the node afterwards. So it is a race condition which results in an error when one of the spin functions tries to add the node while the other has already added it but not yet removed it. Since you're spinning in your thread, there's no need to do http://en.cppreference.com/w/cpp/thread/future/wait or http://en.cppreference.com/w/cpp/thread/future/wait_for or http://en.cppreference.com/w/cpp/thread/future/wait_until |
Looking closer, either of the https://gist.github.com/wjwwood/5667039b95a682e3034b Thanks for reporting the exception that was raised, but I think that it is expected behavior (even if it is not immediately obvious why). Hopefully my answers will help you out. |
Thank you for your advice. I will change the corresponding lines of code in my application. |
The spin functions that do not take a node as an argument maybe thread safe already. But we will make it so or document that it is not as soon as we can. We need to do an api review of rclcpp at some point and at that time we'll more closely consider thread safety and memory allocation related properties. |
Replacing the spin_until_future_complete functions did work for me, but just in case I use:
and not
as you proposed. In the second case I can't access the parameter service (The call fails after a timeout of 5 seconds) |
Hmm, that doesn't sound right, I'll have to try that out locally. |
@firesurfer I think what you've uncovered is another subtle bug (and race condition). I've open a ticket for it here: #209 |
I would really appreciate if it would be possible to implement the spin_until_future_complete function would be implemented threadsafe. By switching to |
@firesurfer why do you need to |
I meant this the other way round. If I use spin in a thread I can't use |
If you're spinning within a library (hidden from the user) and the user also spins, then I'd suggest you should use an executor in your library. Then there should be no problem. The
Then your node and your executor are completely isolated from the user of the library. |
I finally found the time to deal with this problem again. I'm not sure if an extra executor and an extra node are the best solution in my case. I created my library in a way that the user creates a node and passes it to the library like in this pseudocode:
Every Component will create a |
@wjwwood I don't think the spin functions actually use a global singleton executor. Each function initializes its own SingleThreadedExecutor on the stack at the beginning. https://github.com/ros2/rclcpp/blob/master/rclcpp/src/rclcpp/executors.cpp |
@jacquelinekay you're right, I'm not sure if I was just mistaken or if it used to be that way. Either way, now I'm thinking that @firesurfer you may be adding the same node to multiple executors? That might be bad, probably would be bad, but I'm not sure since we've never done that. |
In case of using a spin function and using How is it intended by design to interact with ros 2 publishers and services from multiple threads? Is there any article or design documentation available on how the system with executors and so on works (or is intended to work)? |
If you want to spin in multiple threads, then I'd recommend using the |
I don't think that I designed the node in a wrong way (but perhaps you could point out a better way). I've got some code that does hardware interaction and that should be called as often as possible (was used in another framework before - I simply removed the interaction with the old framework). At first I added the spin_some or spin_once function in the main loop of the program that called the functions for hardware interaction. But in case there was a lot of communication to be done over ros 2 the spin* function took too long. So I moved it into another thread. But I still need to fill in data into messages and publish them and do a parameter service call from time to time from the main loop where the hardware in polled from. So there has to be some interaction between threads. I could surely synchronize all interaction with ros 2 into the same thread, but I would expect from an framework that this kind of multithreaded interaction should be possible. Another simple example I can imagine is simply having a blocking call that waits for keyboard inputs. In this case I think many users will come up with a solution that simply moves the call of the spin function in another thread, so it would still be possible to have interaction via ros 2 in the background. |
In some case, extra slash may casue choas. Fix it anyway Signed-off-by: jwang <[email protected]>
* Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> * Address commments: - Rewrite history - Move sequential reader implementation to header/source - Change namespaces - Linting Signed-off-by: Anas Abou Allaban <[email protected]> * Add visiblity control header Signed-off-by: Anas Abou Allaban <[email protected]> * Address structural review feedback Signed-off-by: Prajakta Gokhale <[email protected]> * Remove extraneous newline Signed-off-by: Prajakta Gokhale <[email protected]> * Add new BaseReaderInterface * Add new reader interface * Use the interface in sequential reader Signed-off-by: Prajakta Gokhale <[email protected]> * Remove extra newline Signed-off-by: Prajakta Gokhale <[email protected]> * Final reader class implementation (ros2#4) * final reader class Signed-off-by: Karsten Knese <[email protected]> * adaptations for rosbag2_transport Signed-off-by: Karsten Knese <[email protected]> * address review comments Signed-off-by: Karsten Knese <[email protected]> * Make BaseReaderInterface public Signed-off-by: Prajakta Gokhale <[email protected]> * Rebase on writer changes Signed-off-by: Karsten Knese <[email protected]> * Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> Introduce new SequentialReader interface Signed-off-by: Anas Abou Allaban <[email protected]> * Address commments: - Rewrite history - Move sequential reader implementation to header/source - Change namespaces - Linting Signed-off-by: Anas Abou Allaban <[email protected]> * Final reader class implementation (ros2#4) * final reader class Signed-off-by: Karsten Knese <[email protected]> * adaptations for rosbag2_transport Signed-off-by: Karsten Knese <[email protected]> * address review comments Signed-off-by: Karsten Knese <[email protected]> * rebase Signed-off-by: Karsten Knese <[email protected]> * structurial changes for rosbag2 Signed-off-by: Karsten Knese <[email protected]> * rosbag2_transport adaptations Signed-off-by: Karsten Knese <[email protected]> * fixes for rebasing Signed-off-by: Karsten Knese <[email protected]> * pragma for windows Signed-off-by: Karsten Knese <[email protected]> * remove unused file Signed-off-by: Karsten Knese <[email protected]> * multifile sequential reader Signed-off-by: Karsten Knese <[email protected]>
See:
https://github.com/firesurfer/Segfault_demo
(I simply reused the demo)
It throws the following exception:
when doing
in another thread.
The exception doesn't get thrown every time but every second or third time the segfault_demo_client is run.
The text was updated successfully, but these errors were encountered: