Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

TBB and sockets

joaomarques
Beginner
556 Views
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
Valued Contributor III
556 Views
Don't you mean "task::spawn_root_and_wait(tb);" instead of "tb.execute();"?
0 Kudos
joaomarques
Beginner
556 Views
yes you are right but can i do it without the "wait" part?
0 Kudos
RafSchietekat
Valued Contributor III
556 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).

0 Kudos
joaomarques
Beginner
556 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
0 Kudos
joaomarques
Beginner
556 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?
0 Kudos
RafSchietekat
Valued Contributor III
556 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.

0 Kudos
joaomarques
Beginner
556 Views
Thank you again for the help.
0 Kudos
Reply