- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey folks,
I'm using TBB to build an app that uses BSD sockets. It's server app therefore i launch a thread that runs the accept() function.
thread_accepts_connect()
{
...
while(1)
{
client_sockfd = accept ();
ProcessSocketTask& fb = *new( tbb::task::allocate_root() ) ProcessSocketTask(client_sockfd);
fb.execute();
}
}
But there are two problems:
1 - Tasks are using I/O.
2 - Memory leaks from ProcessSocketTask
I tried a diferent approach this time instead of using tasks it used threads
problem #1 was solved. But problem #2 was still there.
Threads or Task which is the best approach?
How to release memory from Task or Threads? I don't want to do it on thread_accepts_connect because it needs to be "free" to accept connections.
I'm using TBB to build an app that uses BSD sockets. It's server app therefore i launch a thread that runs the accept() function.
thread_accepts_connect()
{
...
while(1)
{
client_sockfd = accept ();
ProcessSocketTask& fb = *new( tbb::task::allocate_root() ) ProcessSocketTask(client_sockfd);
fb.execute();
}
}
But there are two problems:
1 - Tasks are using I/O.
2 - Memory leaks from ProcessSocketTask
I tried a diferent approach this time instead of using tasks it used threads
problem #1 was solved. But problem #2 was still there.
Threads or Task which is the best approach?
How to release memory from Task or Threads? I don't want to do it on thread_accepts_connect because it needs to be "free" to accept connections.
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't you mean "task::spawn_root_and_wait(tb);" instead of "tb.execute();"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
yes you are right but can i do it without the "wait" part?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps something resembling the following (don't forget to get rid of cpt at some point):
thread_accepts_connect()
{
...
tbb::empty_task& cpt = *new( tbb::task::allocate_root() ) tbb::empty_task;
while(1)
{
client_sockfd = accept ();
ProcessSocketTask& fb = *new( cpt.allocate_additional_child_of( cpt ) ) ProcessSocketTask(client_sockfd);
cpt.spawn(fb);
}
}
(Added) Sorry, that was rushed, and without heeding my own advice to interface I/O to TBB using a concurrent data structure or so, with proper scheduling being program-specific. The suggested code is bad for numerous reasons: there is no bound on the number of tasks spawned before the process runs out of sockets, the tasks will still do I/O and may occasionally block, TBB is unfair even between the spawned tasks, and the tasks may be starved if TBB is otherwise occupied. No likely solution will spawn a task per socket (perhaps per data packet).
(Corrected) allocate_additional_child_of() is not static, but I have not actually verified this (it was rushed, and is probably not worth verifying).
thread_accepts_connect()
{
...
tbb::empty_task& cpt = *new( tbb::task::allocate_root() ) tbb::empty_task;
while(1)
{
client_sockfd = accept ();
ProcessSocketTask& fb = *new( cpt.allocate_additional_child_of( cpt ) ) ProcessSocketTask(client_sockfd);
cpt.spawn(fb);
}
}
(Added) Sorry, that was rushed, and without heeding my own advice to interface I/O to TBB using a concurrent data structure or so, with proper scheduling being program-specific. The suggested code is bad for numerous reasons: there is no bound on the number of tasks spawned before the process runs out of sockets, the tasks will still do I/O and may occasionally block, TBB is unfair even between the spawned tasks, and the tasks may be starved if TBB is otherwise occupied. No likely solution will spawn a task per socket (perhaps per data packet).
(Corrected) allocate_additional_child_of() is not static, but I have not actually verified this (it was rushed, and is probably not worth verifying).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the advice. I'm going for the normal approach of creating a poll of threads and using a concurrent_queue to pop up. Thanks for the help much apprichiated Raf_Schietekat
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just one more question. I've used the code you sugested for a different use but it's giving me this error:
error: cannot call member function 'tbb::internal::allocate_additional_child_of_proxy tbb::task::allocate_additional_child_of(tbb::task&)' without object
What's the problem?
error: cannot call member function 'tbb::internal::allocate_additional_child_of_proxy tbb::task::allocate_additional_child_of(tbb::task&)' without object
What's the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See new correction above, but note the "perhaps" and the correction comment. I defer to others for further suggestions about a likely solution (not by spawning tasks for sockets), I'm curious myself and I'm afraid I have not yet studied Robert Reed's blog; maybe even parallel_for on the file descriptors after select/poll discovers available data, followed by a pipeline on complete packets.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you again for the help.
![](/skins/images/C4F7392A5C68ACA60290C9576F107044/responsive_peak/images/icon_anonymous_message.png)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page