Home > Software engineering >  Resetting class members when using TBB
Resetting class members when using TBB

Time:08-16

I using TBB to load data in a queue in parallel. In the class below, the method load_data works fine. I'm writing the method cancel_load which should cancel the loading process and reset arena and task so that I can restart the loading process from the beginning. After the loading process is stopped, I will clear the queue using clear_queue method.

In the method cancel_load, task.cancel works fine. However, when I try to reset the members arena and task to new instances, I see error: use of deleted function when compiling.

Can anyone explain why this is happening? I have not deleted task object. I'm just trying to reset it using a new instance. Is there a better way to reset these class members?

#include <iostream>
#include <tbb/concurrent_queue.h>
#include <tbb/task_group.h>
#include <tbb/tbb_thread.h>

class ParallelDataset {
    public:
        tbb::concurrent_bounded_queue<record_data::Record> MyQueue;
        tbb::task_arena arena;
        tbb::task_group task;

    ~ParallelDataset()
    {
        task.wait();
    }

    void load_() {
        // start loading data into MyQueue
    }

    void load_data() {
        arena.execute([&]() {
            task.run([&]() { 
                load_();
                    });       
        });
    }

    void cancel_load() {
        task.cancel();
        tbb::task_arena new_arena;
        tbb::task_group new_task;
        arena = new_arena;
        task = new_task;
        std::cout << "Data loading is cancelled. Arena and Task have been reset" << std::endl;
    }

    void clear_queue() {
        MyQueue.clear();
    }
}

Error

/home/src/dataset.cpp: In member function 'void ParallelDataset::cancel_load()':
/home/src/dataset.cpp:275:16: error: use of deleted function 'tbb::task_group& tbb::task_group::operator=(const tbb::task_group&)'
  275 |         task = new_group;
      |                ^~~~~~~~~
In file included from /home/src/dataset.cpp:6:
/usr/include/tbb/task_group.h:192:7: note: 'tbb::task_group& tbb::task_group::operator=(const tbb::task_group&)' is implicitly deleted because the default definition would be ill-formed:
  192 | class task_group : public internal::task_group_base {
      |       ^~~~~~~~~~
/usr/include/tbb/task_group.h:192:7: error: use of deleted function 'tbb::internal::task_group_base& tbb::internal::task_group_base::operator=(const tbb::internal::task_group_base&)'
/usr/include/tbb/task_group.h:92:7: note: 'tbb::internal::task_group_base& tbb::internal::task_group_base::operator=(const tbb::internal::task_group_base&)' is implicitly deleted because the default definition would be ill-formed:
   92 | class task_group_base : internal::no_copy {
      |       ^~~~~~~~~~~~~~~
/usr/include/tbb/task_group.h:92:7: error: use of deleted function 'tbb::internal::no_copy& tbb::internal::no_copy::operator=(const tbb::internal::no_copy&)'
In file included from /usr/include/tbb/task.h:23,
                 from /usr/include/tbb/parallel_for.h:24,
                 from /home/src/dataset.cpp:4:
/usr/include/tbb/tbb_stddef.h:330:7: note: 'tbb::internal::no_copy& tbb::internal::no_copy::operator=(const tbb::internal::no_copy&)' is implicitly deleted because the default definition would be ill-formed:
  330 | class no_copy: no_assign {
      |       ^~~~~~~
/usr/include/tbb/tbb_stddef.h:330:7: error: use of deleted function 'void tbb::internal::no_assign::operator=(const tbb::internal::no_assign&)'
/usr/include/tbb/tbb_stddef.h:324:10: note: declared here
  324 |     void operator=( const no_assign& ) = delete;
      |          ^~~~~~~~
In file included from /home/src/dataset.cpp:6:
/usr/include/tbb/task_group.h:92:7: error: use of deleted function 'tbb::task_group_context& tbb::task_group_context::operator=(const tbb::task_group_context&)'
   92 | class task_group_base : internal::no_copy {
      |       ^~~~~~~~~~~~~~~
In file included from /usr/include/tbb/parallel_for.h:24,
                 from /home/src/dataset.cpp:4:
/usr/include/tbb/task.h:347:7: note: 'tbb::task_group_context& tbb::task_group_context::operator=(const tbb::task_group_context&)' is implicitly deleted because the default definition would be ill-formed:
  347 | class task_group_context : internal::no_copy {
      |       ^~~~~~~~~~~~~~~~~~
/usr/include/tbb/task.h:347:7: error: use of deleted function 'tbb::internal::no_copy& tbb::internal::no_copy::operator=(const tbb::internal::no_copy&)'

CodePudding user response:

The tbb::task_arena and tbb::task_group objects are non-copyable, like you may also know from std::unique_ptr. This is realized by deleted operator=, explaining the compiler's error message.

You have to reinitialize your members in another way or use pointers so you can instantiate their replacements in-place.

In your scenario, I would assume that task.cancel() and arena.terminate() should do the job.

CodePudding user response:

Based on @ypnos comment about using unique pointers, I came up with the following solution that works.

#include <iostream>
#include <tbb/concurrent_queue.h>
#include <tbb/task_group.h>
#include <tbb/tbb_thread.h>

class ParallelDataset {
public:
    tbb::concurrent_bounded_queue<record_data::Record> MyQueue;
    std::unique_ptr<tbb::task_arena> arena;
    std::unique_ptr<tbb::task_group> task;

    ParallelDataset () : arena(std::make_unique<tbb::task_arena>()),
                         task(std::make_unique<tbb::task_group>()) {}

    ~ParallelDataset()
    {
        task->wait();
    }

    void load_() {
        // start loading data into MyQueue
    }

    void load_data() {
        arena->execute([&]() {
            task->run([&]() { 
                load_();
                    });       
        });
    }

    void cancel_load() {
        task->cancel();
        arena = std::move(std::make_unique<tbb::task_arena>());
        task = std::move(std::make_unique<tbb::task_group>());
        std::cout << "Data loading is cancelled. Arena and Task have been reset" << std::endl;
    }

    void clear_queue() {
        MyQueue.clear();
    }
}
  • Related