在C ++中是否可以从主线程中执行辅助线程中运行的函数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C ++中是否可以从主线程中执行辅助线程中运行的函数?相关的知识,希望对你有一定的参考价值。

例如,我有一个主线程,创建了很多类等。我有一个网络部分,即在单独的线程中等待客户端数据。这个“服务员”应该从主线程中创建的类中运行一些函数,这个函数应该在主线程中执行。

我怎么能这样做?如果我这样调用所需的方法SomeClass::SomeMethod(some_args);来自服务员,当然,他们在辅助线程中执行。

会有这样的事情:SomeClass::Invoke(function_pointer);所以,function_pointer指向的函数会在主线程中执行吗?我需要一个关于Windows操作系统的建议。

答案

如果这是Windows Win32应用程序,那么使用应用程序的消息处理队列是一种常见的方法。在您的应用程序的主窗口中,您等待自定义用户消息,通常它将是这样的:

(in header file)
#define WM_MYCUSTOMMESSAGE (WM_USER + 1)

(WndProc for you main window)
LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_MYCUSTOMMESSAGE:
        ... Process something
        break;
    }
}

(On seconday thread)
SendMessage(hWnd, WM_MYCUSOMMESSAGE, wParam, lParam); // Send and wait for the result

PostMessage(hWnd, WM_MYCUSTOMMESSAGE, wParam, lParam); // Send the message and continue this thread.

[编辑]对于控制台应用程序,请尝试使用Windows事件。因此,使用以下命

(On primary thread)
HANDLE myEvent = CreateEvent(NULL, FALSE, FALSE, "MyEvent");

... later as part of a message processing loop
while(true)
{
    WaitForSingleObject( myEvent, 0 ); // Block until event is triggers in secondary thread

    ... process messages here
    ... I recommend storing "messages" in a synchronized queue
}

(On secondary thread)
SetEvent(myEvent); // Triggers the event on the main thread.
另一答案

即使使用调用,该函数仍将在调用它的线程中执行,因此没有用。

在辅助线程中释放的主线程中,您可以在循环内部进行忙等待或互斥,并且在释放时,它会根据三元变量调用某些方法。

//thread1
runThread2();
while (true)
{
   mutex.acquire();
   mutex.lock();
   switch(command)
   {
      case command_noop:
         sleep(1000);
         break;
      case command1:
         foo1();
         break;
      case command2:
         foo2();
         break;
      //and so on...
   }
   mutex.release();
}

//thread2:
mutex.lock();
//commands
command = 1;
mutex.release();
mutex.acquire();
//rest of commands
另一答案

在Embarcadero C ++ Builder中,有函数TThread::QueueTThread::Synchronize,它们可用于在主线程中执行函数。这适用于任何线程,它不一定是TThread

#include <vcl.h>
#include <functional>

namespace {

class wrapper : public TCppInterfacedObject<TThreadProcedure> {
public:
    wrapper(std::function<void(void)> f) : f_(f) {}

    void __fastcall Invoke() {
        f_();
    }
private:
    std::function<void(void)> f_;
};

const unsigned int main_thread = GetCurrentThreadId();

} // namespace


// Execute the function asynchronously in main thread
void queue_to_main_thread(std::function<void(void)> f)
{
    if (GetCurrentThreadId() == main_thread) {
        f();
    }
    else {
        TThread::Queue(NULL, _di_TThreadProcedure(new wrapper(f)));
    }
}

// Execute the function synchronously in main thread
void synchronize_to_main_thread(std::function<void(void)> f)
{
    if (GetCurrentThreadId() == main_thread) {
        f();
    }
    else {
        TThread::Synchronize(NULL, _di_TThreadProcedure(new wrapper(f)));
    }
}

以上是关于在C ++中是否可以从主线程中执行辅助线程中运行的函数?的主要内容,如果未能解决你的问题,请参考以下文章

在C ++中,是否有任何理由产生并立即加入一个线程,而不是直接调用该函数?

是否可以在线程中对非托管函数执行C#回调?

volatile关键字 - 内存可见性

详解c++11多线程

java 如何获得线程池中正在执行的线程数?

高分求qt写的线程程序,功能每隔一百毫秒查询数据,这个线程在整个程序运行中都一直在运行