6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80

std::thread чудит?

02.10.2020, 10:04. Показов 3278. Ответов 25

Студворк — интернет-сервис помощи студентам
Доброго времени суток!

Столкнулся с, на мой взгляд, странной проблемой. Есть код примерно следующего содержания:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CVC_Data_Saving(std::future<double*> &CVC_Point, unsigned int &Cursor, double *CVC_Data, bool it);
 
void SomeFunc(unsigned int Points)
{
  std::future<double*> CVC_Point[2];        //Два фьючерса, они по очереди используются
  unsigned int Cursor = 0u;                        //Курсор для хранения места в массиве, куда надо писать следующую порцию данных
  double* CVC_data = new double[Points];  //Собсна, массив данных размера Points
 
  std::thread Thread(CVC_Data_Saving, CVC_Point[0], Cursor, CVC_data, true);
  Sleep(Delay);
  Thread.join();
 
  ...
}
Наличие задержки здесь может казаться глупым, но она нужна в силу некоторых физических ограничений в оборудовании, для которого пишется код. Проблема не в этом. Проблема в том, что эта штука не компилируется, и я не понимаю, почему. Компилятор MinGW GCC ругается на открытие потока, выдает примерно следующее (весь текст ошибки не привожу, он довольно большой, только самую суть):



C:/Qt/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/thread: In instantiation of 'struct std::thread::_Invoker<std::tuple<void (ADC_Routine::*)(std::future<double*>&, unsigned int&, double*, bool), ADC_Routine*, std::future<double*>, unsigned int, double*, bool> >':
C:/Qt/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/thread:127:22: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (ADC_Routine::*)(std::future<double*>&, unsigned int&, double*, bool); _Args = {ADC_Routine*, std::future<double*>&, unsigned int&, double*&, bool}]'

C:/Qt/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/thread:231:4: note: template argument deduction/substitution failed:



Дескать, передаю неправильные аргументы. Но почему?? Компилятор почему то считает, что при передаче указателя CVC_data он вдруг становится не double*, a double*&! Правда, я пробовал убрать его из функции, компилятор все равно ругается на то же самое, хотя список принимаемых и передаваемых аргументов оказывается одинаковым.

Есть у кого-то мысли по поводу того, почему возникает ошибка компиляции?

Заранее благодарю за уделенное время.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.10.2020, 10:04
Ответы с готовыми решениями:

Использование std::function в std::thread
Нужно вызвать function fnc в новом потоке. Как сделать? function &lt;void(vector&lt;char&gt;)&gt; fnc; void test(vector&lt;char&gt; data) { ...

Ошибка компиляции "no instance of constructor 'std::thread::thread' matches the argument list"
Не могу сообразить почему возникает ошибка. У меня в классе есть метод, который должен работать в нескольких потоках одновременно. Вот он: ...

Boost::thread vs std::thread
Доброго времени суток, решил углубить свои знания, и решил почитать про потоки, бустовые и те что в 11 стандарте приняли, с бустом все ясно...

25
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.10.2020, 14:30
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
НО! Я предполагаю в программе, что большая часть обработки происходит во время SLeep.
Во время Sleep у тебя вроде просто копирование памяти и ты по-любому потом ждёшь завершения этой операции. Так что в этом потоке точно никого смысла
0
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
02.10.2020, 14:34  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну а вообще, я к тому, что такое ощущение, что с потоками здесь геморроя и накладных расходов намного больше, чем пользы. Без них этот код будет проще и будет работать быстрее.
Код - возможно, быстрее, но есть еще реальное высоковольтное железо, которому плевать на код, и работает оно по совсем другим законам.

Добавлено через 3 минуты
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Во время Sleep у тебя вроде просто копирование памяти и ты по-любому потом ждёшь завершения этой операции. Так что в этом потоке точно никого смысла
Возможно, но мне пока это не очевидно, так как жду я все таки не копирования, а конца обработки, возможно, большого количества данных. Но тут я согласен, что этот момент можно оптимизировать, так как, по крайней мере, фьючерсы могут простаивать без дела. Я об этом еще подумаю, но пока оно работает с удовлетворяющей меня скоростью.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.10.2020, 14:40
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Возможно, но мне пока это не очевидно, так как жду я все таки не копирования, а конца обработки, возможно, большого количества данных. Но тут я согласен, что этот момент можно оптимизировать, так как, по крайней мере, фьючерсы могут простаивать без дела. Я об этом еще подумаю, но пока оно работает с удовлетворяющей меня скоростью.
Вот однопоточный аналог твоей функции. По-моему даже в таком виде он будет работать лучше.

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
25
26
27
28
29
    for (double Cur_Voltage = KV_Start; Cur_Voltage <= KV_Fin; Cur_Voltage += KV_Step)
    {
        //Выставляем текущее напряжение
        SetDAC((Cur_Voltage / MAX_KV) * DAC_MAX_VOLT, 0x0);
 
        const auto tm = std::chrono::steady_clock::now() + std::chtono::milliseconds(Delay);
 
        ADC_Routine::CVC_Data_Saving(....................);
 
        const auto tm2 = std::chrono::steady_clock::now();
        if (tm2 < tm)
            std::this_thread::sleep_for(tm2 - tm);
 
        this->ADC_Work();
 
        if (this->ReadThreadErrorNumber)
            break;
 
 
        ADC_Routine::CVC_Data_Proc(...........................);
 
        ++it;
 
        if((double)it / (double)Point_Count >= PercIncrValue * Perc_Counter)
        {
            emit PercIncr((unsigned int)(Perc_Counter * PercIncrValue * 100.0));
            ++Perc_Counter;
        }
    }
Там у тебя ошибка была с if(!this->ReadThreadErrorNumber)
1
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
02.10.2020, 14:49  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Там у тебя ошибка была с if(!this->ReadThreadErrorNumber)
Эм... нет. У меня там написано, что если ошибок нет, то что-то делаем. Единственно что - там не хватает else break;

Хотяя... Пожалуй, в том, что выставлять задержку только, если обработка затянулась, не открывая потока, что-то есть... Тут мне придется согласиться. Я пытался сделать так, чтобы если расчеты затянулись, прога не ждала бы их окончания, а работала дальше - хоть бы и задержку выставляла, потому что вот это: ADC_Routine::CVC_Data_Proc(............. ..............); - выполняется долго.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
02.10.2020, 14:58
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Я пытался сделать так, чтобы если расчеты затянулись, прога не ждала бы их окончания, а работала дальше - хоть бы и задержку выставляла, потому что вот это: ADC_Routine::CVC_Data_Proc(............. ..............); - выполняется долго.
Ты в любом случае будешь ждать её завершения перед следующей итерацией. Единственное, на чём ты там можешь сэкономить, это Sleep. Я тебе показал как сделать эту задержку без создания потоков.

Добавлено через 1 минуту
Цитата Сообщение от Юрий Мамонтов Посмотреть сообщение
Единственно что - там не хватает else break;
Ну да, это и была ошибка, причём довольно серьёзная
1
6 / 6 / 0
Регистрация: 27.11.2016
Сообщений: 80
02.10.2020, 14:58  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Я тебе показал как сделать эту задержку без создания потоков.
Да, это я понял, спасибо большое за идею)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.10.2020, 14:58

Boost::thread std::thread
чем отличается boost::thread( ) от std::thread (с++17)? я спрашиваю не о способе реализации потоков в целом, а конкретно о этих функциях....

std::thread
Возник вопрос: как создать массив потоков (точнее, как его инициализировать). То есть, мне нужно примерно такое: std::thread...

Std::thread::detach()
Что произойдет, если main - поток завершится раньше чем child.detach()? Добавлено через 3 минуты У меня программа просто завершилась...

Конструктор std::thread
Доброго времени суток, помогите, пожалуйста, понять, в чем ошибка? #include &lt;functional&gt; #include &lt;algorithm&gt; #include...

Указатели и std::thread
Всем здрасьте ! Возникла проблема в понимании ... Возможно я написал не в ту тему, но думаю тут есть эксперты. У меня есть класс...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Опции темы

Новые блоги и статьи
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru