C ++ 11 packaged_task, работающий со своим собственным потоком, нуждается в join (), чтобы получить будущее

Из книги C ++ 11, которую я недавно получил, я пытаюсь построить пример на странице 123 (packaged_task 5.3.5.2), и после нескольких вещей, чтобы сделать это с помощью XCode, у меня есть пара вопросов:

Во-первых, кажется, есть требование передать указатель на функцию в упакованный_так. Текст не показывает амперсанд, так что, может быть, это опечатка или изменение в конце стандарта?

Затем, и что более важно, мне пришлось добавить thread.join (s), чтобы можно было вызывать get и избегать получения sigabrt, и процесс завершается без печати чего-либо. У меня сложилось впечатление, что вызов get будущего будет блокироваться до тех пор, пока поток не вернет значение, но, похоже, это не так. Добавление объединения также, кажется, игнорирует асинхронную (неблокирующую) природу кода. Почему нельзя в будущем сделать объединение самостоятельно, если это необходимо? Читая из документов, он говорит, что get будет вызывать неявное ожидание, и даже если добавить код в ожидании, это все равно вызывает sigabrt. Это очень загадочно.

Я использую диалект языка c11, -std = gnu ++ 11 и libc ++ (с поддержкой c ++ 11). Я попробовал другие варианты без удачи (при использовании gnuc ++ он не может найти). Кажется, это единственные комбинации, которые я могу использовать для создания кода. XCode очень требователен к тому, что нужно для компиляции c ++ 11.

Заранее благодарны за Вашу помощь.

Вот тестовый пример из книги с моими «исправлениями» для запуска кода:

    #include <iostream>
#include <numeric>
#include <vector>
#include <thread>
#include <future>

using namespace std;

double accum(double *beg, double *end, double init)
{
return accumulate(beg, end, init);
}

double comp2(vector<double>& v)
{

using Task_type = double(double*,double*,double);

packaged_task<Task_type> pt0 {&accum}; //use '&' to compile
packaged_task<Task_type> pt1 {&accum}; //use '&' to compile

future<double> f0 {pt0.get_future()};
future<double> f1 {pt1.get_future()};

double* first=&v[0];
thread t1 {move(pt0), first, first+v.size()/2, 0};
thread t2 {move(pt1), first+v.size()/2, first+v.size(), 0};

// need this to run
t1.join();
t2.join();

// using this instead of the join doesn't work
//      f0.wait();
//      f1.wait();

return f0.get() + f1.get();
}

int main()
{
vector<double> v {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cout<<comp2(v)<<endl;
return 0;
}

1

Решение

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

1

Другие решения

Вам нужно вызвать join () в потоке или отсоединить его. Это вопрос? В этом случае packaged_task может использоваться для обеспечения безопасности исключений, но у вас все еще есть пара потоков, которые запускают шоу.

0

Я думаю, что текущие ответы не ответили на вопрос напрямую. Вам не нужно явно создавать потоки для запуска задач. Например:

#include <future>
#include <stdexcept>
#include <iostream>
#include <thread>
#include <utility>
#include <functional>

using namespace std;

int ff(int i)
{
return i;
}

int main(int argc, char *argv[])
{

packaged_task<int(int)> pt1 (ff);
auto v1 = pt1.get_future();
thread t1(move(pt1), 1);
t1.join();

packaged_task<int(int)> pt2(ff);
auto v2 = pt2.get_future();
pt2(1);
cout << v2.get() << endl;

return 0;
}

Если вы скомпилируете приведенный выше пример, вы увидите 1 как стандартный вывод.

Но что меня смутило, так это то, что если я закомментирую первый packaged_task, то вижу std::system_error, полный код:

#include <future>
#include <stdexcept>
#include <iostream>
#include <thread>
#include <utility>
#include <functional>

using namespace std;

int ff(int i)
{
return i;
}

int main(int argc, char *argv[])
{

// packaged_task<int(int)> pt1 (ff);
// auto v1 = pt1.get_future();
// thread t1(move(pt1), 1);
// t1.join();

packaged_task<int(int)> pt2(ff);
auto v2 = pt2.get_future();
pt2(1);
cout << v2.get() << endl;

return 0;
}

Очевидно, что два packaged_tasks независимы, но удаление первого вызовет сбой второго с system_error,

Это не ответ на вопрос, а попытка уточнить вопрос.

0
По вопросам рекламы [email protected]