Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
-1 / 1 / 0
Регистрация: 24.12.2018
Сообщений: 124
1

Передача функторов в поток

24.09.2020, 19:12. Показов 2163. Ответов 16

Author24 — интернет-сервис помощи студентам
В классе создан вектор указателей на функторы.
Я хочу запустить все функторы в отдельных потоках - см. функцию func().
Какой должен быть синтаксис, чтобы это сделать?


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class MyClass
{
    struct MyClassParameters
    {
        unsigned int ddddddd;
        unsigned int rrrrrrr;
        unsigned int zzzzzzz;
 
    } MyClass_Sett;
 
    int func(CShortVec& input1, CDoubleArr& output1);    // в этой функции нужно использовать вектор указателей на функторы
 
    // Создаем функтор
    struct GetData
    {
        int operator()(CShortVec& input1, CDoubleArr& output1, MyClass & obj) 
        {
            if ( obj.MyClass_Sett.ddddddd < 0) return 0;    
            for (unsigned int i = 0; i < copyData.size(); i++) output1[i] = input1[i];
            return 0;
        }
    };
    std::vector<GetData*> copyData;  // Объявляем вектор указателей на функторы
}
Потом в конструкторе инициализирую вектор указателей на функторы:
C++
1
2
3
4
5
MyClass::MyClass()
{
    copyData.resize(10);
    for (unsigned int i = 0; i < copyData.size(); i++) copyData[i] = new GetData;
}
Теперь хочу запустить все функторы в отдельных потоках
C++
1
2
3
4
5
6
7
8
int MyClass::func(CShortVec& input1, CDoubleArr& output1)
{
    // Как запустить нужное количество потоков 
    for (unsigned int i = 0; i < copyData.size(); i++) {   };
 
    // Это запуск одного потока с функтором - так не работает
    std::thread thread_rx1(&MyClass::copyData[0],this,std::ref(input1), std::ref(output1));
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.09.2020, 19:12
Ответы с готовыми решениями:

Перегрузка функторов в STL
Просто любопытно, заметил такую вещь: есть скажем перегруженая функция show(int &amp;a) и show(string&amp;...

Как создать вектор функторов
Хочу создать вектор указателей на функторы в классе. Как это правильно сделать? class MyClass...

Передача переменных в поток
Вот никак не могу разобраться, как передать переменную в функцию потока. Вот например есть код: ...

C++ 11 передача ссылки в поток thread
Доброго времени суток, возникла такая ситуация. Использую я QT Creator с компилятором MinGW32...

16
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,076
24.09.2020, 19:16 2
Цитата Сообщение от prokino Посмотреть сообщение
// Как запустить нужное количество потоков
Объявить std::vector<std::thread> и в цикле делать push_back или emplace_back в него ваших потоков по одному.

Цитата Сообщение от prokino Посмотреть сообщение
// Это запуск одного потока с функтором - так не работает
Разумеется, уничтожать std::thread до того, как завершится поток, не разрешается. Поэтому либо ждите завершения потока, либо позаботьтесь о правильном времени жизни объектов std::thread.
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
24.09.2020, 19:18 3
Цитата Сообщение от prokino Посмотреть сообщение
std::thread thread_rx1(&MyClass::copyData[0],this,std::ref(input1), std::ref(output1));
C++
1
2
3
4
std::thread thread_rx1([this, &input1, &output1]()
{
    (*copyData[0])(input1, output1, *this);
});
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,076
24.09.2020, 19:19 4
Цитата Сообщение от prokino Посмотреть сообщение
std::thread thread_rx1(&MyClass::copyData[0],
Что такое &MyClass::copyData[0]? Первым параметром должен быть собственно функтор потока.
0
6105 / 3460 / 1406
Регистрация: 07.02.2019
Сообщений: 8,799
24.09.2020, 19:20 5
Цитата Сообщение от prokino Посмотреть сообщение
C++
1
std::vector<GetData*> copyData;  // Объявляем вектор указателей на функторы
Зачем всё это?
Ваш функтор весит 1 байт, более того он вообще не захватывает никаких данных.
Так же он не полиморфный.
1
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
24.09.2020, 19:23 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int MyClass::func(CShortVec& input1, CDoubleArr& output1)
{
    std::vector<std::future<int>> futs;
    // Как запустить нужное количество потоков 
    for (unsigned int i = 0; i < copyData.size(); i++) 
        futs.emplace_back(std::async([fn = copyData[i], this, &input1, &output1]()
        {
            (*fn)(input1, output1, *this);
        });
 
    for (auto &item: futs)
        item.get();
}
1
-1 / 1 / 0
Регистрация: 24.12.2018
Сообщений: 124
25.09.2020, 11:57  [ТС] 7
oleg-m1973, предложенный вариант хорош.
Но если предложенный код немного изменить, то возникают некоторые ошибки, с которыми прошу помочь разобраться.

В функцию func() передаются ссылки на входные массивы данных.
В классе MyClass есть свои массивы output1, output2, output3, output4.
Функция func() принимает входные массивы данных, обрабатывает их функторами и результаты складывает в output1...output4

Лямбда ругается на inputVects[i], outputVects[i].


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int MyClass::func(CShortVec& input1, CShortVec& input2, CShortVec& input3, CShortVec& input4)
{
    // Помещаем все ссылки на входные массивы в вектор
    std::vector<CShortVec> inputVects = {input1, input2, input3, input4};
 
    // Помещаем все указатели на выходные массивы в вектор
    std::vector<CDoubleArray> outputVects = {output1, output2, output3, output4};
 
    std::vector<std::future<int>> futs;
    // Запускаем нужное количество потоков 
    for (unsigned int i = 0; i < copyData.size(); i++) 
        // Передаем в потоки указатели на функторы, а также входные и выходные массивы
        futs.emplace_back(std::async([fn = copyData[i], this, inputVects[i], outputVects[i]]()
        {
            (*fn)(input1, output1, *this);
        });
 
    for (auto &item: futs)
        item.get();
}
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
25.09.2020, 13:11 8
Цитата Сообщение от prokino Посмотреть сообщение
Лямбда ругается на inputVects[i], outputVects[i].
C++
1
2
3
4
 futs.emplace_back(std::async([fn = copyData[i], this, i, &inputVects, &outputVects]()
        {
            (*fn)(inputVects[i], outputVects[i], *this);
        });
Добавлено через 1 минуту
А вообще, непонятно, что ты пытаешься сделать
0
-1 / 1 / 0
Регистрация: 24.12.2018
Сообщений: 124
25.09.2020, 14:17  [ТС] 9
Я хочу обработать каждый входной массив в отдельном потоке, а результаты обработки сохранить в другие массивы.
Теперь ошибка в этом месте

C++
1
2
3
4
futs.emplace_back(std::async([fn = copyData[i], this, i, &inputVects, &outputVects]()
        {
            (*fn)(inputVects[i], outputVects[i], *this); // <-- здесь [B]error: no matching function for call to 'std::future<int>::future(std::future<void>)'[/B]
        });
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
25.09.2020, 14:20 10
Цитата Сообщение от prokino Посмотреть сообщение
Теперь ошибка в этом месте
C++
1
2
3
4
futs.emplace_back(std::async([fn = copyData[i], this, i, &inputVects, &outputVects]()
        {
            return (*fn)(inputVects[i], outputVects[i], *this); // <-- здесь [B]error: no matching function for call to 'std::future<int>::future(std::future<void>)'[/B]
        });
Добавлено через 30 секунд
Как-то надо уже самому научиться исправлять такие ошибки
0
-1 / 1 / 0
Регистрация: 24.12.2018
Сообщений: 124
25.09.2020, 14:51  [ТС] 11
Учусь.
Теперь такие проблемы:
1) Со звездочкой перед this программа не работает
C++
1
return (*fn)(inputVects[i], outputVects[i], *this); // ошибка: no matching function for call to object of type 'MyClass::GetData'
2) Если звездочку убрать, то нет сообщений об ошибках, но в массивы output1...output4 ничего не записывается.
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
25.09.2020, 14:55 12
Цитата Сообщение от prokino Посмотреть сообщение
Теперь такие проблемы:
1) Со звездочкой перед this программа не работает
А без потока твои функции работают?
C++
1
2
for (unsigned int i = 0; i < copyData.size(); i++) 
        (*copyData[i])(inputVects[i], outputVects[i], *this);
И покажи, как сделал.
0
51 / 149 / 33
Регистрация: 29.06.2019
Сообщений: 1,428
25.09.2020, 15:10 13
Цитата Сообщение от prokino Посмотреть сообщение
Со звездочкой перед this
прогуглите этот this - это скрытый указатель... думаю, звёздочка в нём уже заложена... имхо
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
25.09.2020, 15:15 14
Цитата Сообщение от JeyCi Посмотреть сообщение
прогуглите этот this - это скрытый указатель... думаю, звёздочка в нём уже заложена... имхо
Не, не заложена. this - это указатель, а *this - ссылка.
Там проблема в параметрах функции - я тупо не знаю, что туда нужно предавать, т.к. вижу только какой-то кусок кода. А ТС, похоже, вообще слабо представляет, что происходит.
1
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
25.09.2020, 16:36 15
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
*this - ссылка
Нет.
0
-1 / 1 / 0
Регистрация: 24.12.2018
Сообщений: 124
25.09.2020, 17:54  [ТС] 16
оба варианта работают без звездочки перед this:

C++
1
2
...........(*fn)(inputVects[i], outputVects[i], this);
...........(*copyData[i])(inputVects[i], outputVects[i], this);
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
25.09.2020, 17:58 17
Цитата Сообщение от prokino Посмотреть сообщение
оба варианта работают без звездочки перед this:
Ну, значит такая у тебя функция. Делай без звёздочки. Потоки здесь ни при чём.
0
25.09.2020, 17:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.09.2020, 17:58
Помогаю со студенческими работами здесь

Передача копии адреса в поток
Всем привет. Проблема в том что когда запускается поток итератор уже указывает за пределы листа....

Передача в поток многомерных массивов по указателю
Доброго всем времени суток. У меня возникло непонимание того, как можно передать двумерный...

Передача в поток
Доброго дня, ребята подскажите как правильно реализовать bool Unlocker(AnsiString FileName) //...

Передача параметров в поток
Почему в потоке (точнее в функции, которую он отрабатывает) после преобразования указателя &quot;r2&quot; к...

Передача параметров в поток
Помогите пожалуйста, не могу понять, как правильно передать параметр в поток. printf(&quot;Listening...

Передача параметров в поток
Добрый день. Имеется основная форма, где объявлена переменная AnsiString LineMessage. Там же в нее...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru