Community
cancel
Showing results for 
Search instead for 
Did you mean: 
joaomarques
Beginner
58 Views

TBB and sockets

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.



0 Kudos
7 Replies
RafSchietekat
Black Belt
58 Views

Don't you mean "task::spawn_root_and_wait(tb);" instead of "tb.execute();"?
joaomarques
Beginner
58 Views

yes you are right but can i do it without the "wait" part?
RafSchietekat
Black Belt
58 Views

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).

joaomarques
Beginner
58 Views

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
joaomarques
Beginner
58 Views

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?
RafSchietekat
Black Belt
58 Views

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.

joaomarques
Beginner
58 Views

Thank you again for the help.