Говорят, что, thread_local, есть одна копия на поток.
Таким образом, если поток threadPool (назовите его A) создал другой поток (назовите его B), переменные thread_local (local_work_queue) в потоке A и B — это две разные вещи.
Поэтому я путаю, что когда задача саммита пула в потоке A (int main ()), как он может получить доступ к local_work_queue в подпотоке B ??? они совершенно не имеют значения.
Функция submit находится в потоке пула, а local_work_queue только init в подчиненном элементе, поэтому в функции submit local_work_queue всегда будет иметь значение nullptr, не так ли?
Ниже приведен код:
class thread_pool
{
typedef std::queue<function_wrapper> local_queue_type;
static thread_local std::unique_ptr<local_queue_type> local_work_queue;
std::vector<std::thread> threads;`
thread_pool()
{
unsigned const thread_count=std::thread::hardware_concurrency();
for(unsigned i=0;i<thread_count;++i)
{
threads.push_back(
std::thread(&thread_pool::worker_thread,this,i));
}
}
void worker_thread()
{
local_work_queue.reset(new local_queue_type); //just init in the sub thread
while(1)
{
function_wrapper task;
if(local_work_queue && !local_work_queue->empty())
{
task=std::move(local_work_queue->front());
local_work_queue->pop();
task();
}
else
{
std::this_thread::yield();
}
}
}
template<typename FunctionType>
std::future<typename std::result_of<FunctionType()>::type>submit(FunctionType f)
{
typedef typename std::result_of<FunctionType()>::type result_type;
std::packaged_task<result_type()> task(f);
std::future<result_type> res(task.get_future());
if(local_work_queue) //function submit is in pool thread, and local_work_queue only init in sub thred, so in this ,local_work_queue will away nullptr, isn't it? so confuse how the code work.
{
local_work_queue->push(std::move(task));
}
return res;
}
};
void func()
{
std::cout<<"test"<<std::endl;
}
int main()
{
thread_pool p;
p.submit(func);
}
но вы сделали это статичным. Так будет ли он доступен через класс? что сверх правила thread_local я предполагаю.
увидеть Класс хранения
5) Ключевое слово thread_local разрешено только для объектов, объявленных в области пространства имен, объектов, объявленных в области блока, и статических членов данных. Это указывает на то, что объект имеет длительность хранения потока. Его можно комбинировать со static или extern, чтобы указать внутреннюю или внешнюю связь (за исключением статических элементов данных, которые всегда имеют внешнюю связь), соответственно, но эта дополнительная static не влияет на продолжительность хранения.
его время жизни локально, но связь, я думаю, широка.
Других решений пока нет …