Skip to content

Possible deadlock on service which only happens if you have a single core (thus likely target or VM) #2029

@AlexisTM

Description

@AlexisTM

Bug report

Calling a service client from a RO2 callback causes a deadlock.
The widely used solution is to make use of a Multithreaded Executor.
Yet, this will fail if the VM/target has only 1 core/1 core assigned as the default number of threads is the number of cores.

The biggest problem I see is for libraries requiring 2+ threads relying on the default ctor of the Multithreaded executor, which will not work for some targets. Having them needed to modify all third party executors to define the default number of threads to 2 instead of 0 will eventually cause problems.

Required Info:

  • Operating System:
    • Apertis Pro v2022
  • Installation type:
    • From source
  • Version or commit hash:
  • DDS implementation:
    • Fast-RTPS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

1- Create a single core VM
2- Have a multithreaded executor with default number of threads (0)
2- Use a service 

Expected behavior

We have multiple threads thus the deadlock is prevented.

Actual behavior

The Multithreaded executor uses a single thread as we have a single core on the machine. The application deadlocks.

Feature request

Feature description

The Multithreaded executor defaults to 2+ when the number of threads is defined to 0.

Implementation considerations

When the number of threads is defined to 0, the Multithreaded Executor defaults to std::max(nproc, 2); number of threads.

Another solution is to default it to 2 to have a reproducible behavior thus developers defining the number of threads according to their needs instead of bumping to 128 threads per node for the latest thread-ripper and 1 on limited targets.

When the speed is primordial and the number of threads is a feature, we could have an option such as the threads provided would be the minimum number of threads with a thread policy such as CONSERVATIVE or GREEDY. Node defined (the library maintainer knows better) or configuration defined (the library user knows better)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions