-
Notifications
You must be signed in to change notification settings - Fork 1
ThreadPool: Add get_thread_index() #100
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
Conversation
|
BTW: Did you notice this is MR 100? 🍾 🎆 🥳 🎉 |
soerengrunewald
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from the minor comment, it looks ok to me, so I will give it a 👍
[why] There are use cases in which it is beneficial to know on which of the N pool threads a function gets executed. [how] Store a thread-local thread index when launching the threads. Return this index when called from a worker thread. For other threads, the thread-local index gets initialized to the maximum value of size_t; if this value is found, get_thread_index() throws an exception. Co-authored-by: Soeren Grunewald <soeren.grunewald@desy.de> Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why] We have extended the API by adding ThreadPool::get_thread_index(). Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
9cb704e to
9f161c1
Compare
|
Hmm, what can I, as a user, do with the The index exposes internals that we probably do not want to expose (apart from other things). Maybe there is another way to solve Sascha's problem; would be good to know why he thinks he needs the index of the thread in the vector. Which for example assumes there is a order of the threads in the pool, or that the pool is held in some array kind structure etc pp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a new concept, there is no order and no indexes before this change.
It is rather an implementation detail.
Maybe we want to return a get_thread_Id() instead? Analogous to TaskId. That would leak nothing (even if technically the same value).
But without knowledge of the problem - which has not been described in the PR description - we can not judge what this is all about.
I.e.: Not approve (yet)
See https://mcs-gitlab.desy.de/doocs/doocs-core-libraries/clientlib/-/merge_requests/321 for Sascha's merge request. Yes, I guess one could argue that we expose implementation details with |
This is the solution used now by Sascha, but it would be much less complicated if one could just ask the pool about a thread index.
In a nutshell, it is about using resources that are bound to one specific thread. Thread #0 should access resource #0, thread #1 should access resource #1, and so on. And injecting the data into the thread via TLS or so does not seem to be an option. I guess one of the questions is: Does adding |
I can not really see
Why not call it But if we call it Maybe you can point me to the use case in the PR, it is rather big and has numerous discussions ;-) |
To my understanding, |
|
Hmm, as far as I can see the But there is no guarantee that the thread pool worker with And interestingly the hangup task gets the index as captured value hangup_task_[ldap_indx]
= pool_->add_task([this, ldap_indx]() { hang_up(ldap_indx); }, hangup_duration_);Ah now I get it, the resources held in 🤔 |
Finii
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, at least I think we should/could call this ID, even if it is the index.
But then, when I look into NameService.* I wonder why this solution has been choosen. A lot pre-created LdapConnection objects stored as shared ptr in a ("global") vector. Not even a std::array 🤔 Ah this is to not-initialize the ldap connection "often".
Some other idea to solve this:
A ThreadPool could also handle resources that the workers usually need (in this case LdapConnection objects).
For me that would be the more natural change. Then NameService does not need to store the connections itself but offloads that to the thread pool; and the thread in the pool always has its own resource, guaranteed.
The change is a bit tricky because we generally do not know the type of the resource that each thread needs and it is hard(er) to specify. I mean, in C-isch land the ThreadPool could store unique-ptr to void ;) and the ThreadPool::ThreadPool() gets a factory function pointer or similar to produce that resource ptrs.
I can not see the solution clearly, but that would need some experiments, but I have the feeling that such an approach would also make the NameService stuff more clear. It looks a lot like he worked around the problem that thread-pool threads can not have precreated resources, and that seems to be not a very strange request. So the ThreadPool could maybe gain something from the problem and not just bare solve the issue.
🤔
Yes, that could be an idea, but that would clearly be another PR. |
[why] To avoid this being associated with an index into some array, because users cannot actually index anything in the ThreadPool. [how] Introduce a member type ThreadId and rename member functions and variables accordingly (get_thread_id() etc.). Proposed-by: Ulf Fini Jastrow <ulf.fini.jastrow@desy.de> Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
140f60f to
3f915d3
Compare
|
Sorry, I messed up the last commit. It is corrected now, and the checks pass. |
Finii
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Thanks a lot, @soerengrunewald and @Finii! |

[why]
There are use cases in which it is beneficial to know on which of the N pool threads a function gets executed. Sascha recently came up with one such case for the new clientlib NameService.
[how]
Store a thread-local thread index when launching the threads. Return this index when called from a worker thread. For other threads, the thread-local index gets initialized to the maximum value of size_t; if this value is found, get_thread_index() throws an exception.