在调用它时删除仿函数是否安全?

时间:2011-11-07 14:33:50

标签: c++ windows multithreading undefined-behavior

假设我有以下代码:

typedef std::function<void ()> func_type;

void some_func()
{
  // Irrelevant stuff here. Might take some time...
}

DWORD WINAPI thread_proc(LPVOID lpParameter)
{
  func_type& func = *static_cast<func_type*>(lpParameter);

  func();

  return 0;
}

int main()
{
  HANDLE handle;

  {
    std::function<void ()> my_func(some_func);

    handle = ::CreateThread(NULL, 0, &thread_proc, &my_func, 0, NULL);

    // Here we consider my_func won't be destroyed before its operator() is called in the other thread.
    // I know nothing guarantees that, but let's just say it does for this sample.
  }

  ::WaitForSingleObject(handle, INFINITE);

  return EXIT_SUCCESS;
}

我当前的实现似乎有效,但这并不能证明我没有面对未定义的行为。

此处my_func 可能在调用operator()之前被销毁。但由于我没有在my_func的任何地方引用some_func(),这真的是一个问题吗?

注意:遗憾的是,我无法使用std::threadboost::thread。我希望我能。

2 个答案:

答案 0 :(得分:3)

如果在func()发生之前它被销毁,那么你就是在无效对象上调用成员函数。您需要制作至少要等到func()电话的副本。

答案 1 :(得分:2)

这肯定是UB。您的评论不正确,没有任何内容可以保证在本地销毁之前调用operator()。事实上,我认为它很可能在新线程开始执行之前被销毁。这样做:

typedef std::function<void ()> func_type;

void some_func()
{
  // Irrelevant stuff here. Might take some time...
}

DWORD WINAPI thread_proc(LPVOID lpParameter)
{
  func_type* func = static_cast<func_type*>(lpParameter);

  (*func)();

  delete func;

  return 0;
}

int main()
{
  HANDLE handle;

  {
    func_type* my_func = new func_type(some_func);

    handle = ::CreateThread(NULL, 0, &thread_proc, my_func, 0, NULL);
  }

  ::WaitForSingleObject(handle, INFINITE);

  return EXIT_SUCCESS;
}