Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;要从次线程中运行的函数在主线程中执行函数?_C++_Multithreading - Fatal编程技术网

C++ 在C++;要从次线程中运行的函数在主线程中执行函数?

C++ 在C++;要从次线程中运行的函数在主线程中执行函数?,c++,multithreading,C++,Multithreading,例如,我有一个主线程,创建了许多类等。我有一个网络部分,在单独的线程中等待客户端数据。这个“服务员”应该从主线程中创建的类中运行一些函数,这些函数应该在主线程中执行 我怎么能这样做?如果我这样调用所需的方法SomeClass::SomeMethod(some_args)

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

我怎么能这样做?如果我这样调用所需的方法
SomeClass::SomeMethod(some_args)
最好有这样的东西:

SomeClass::Invoke(函数指针)即使使用了invoke,函数仍然会在调用它的线程中执行,因此这是没有用的

您可以在循环内的主线程(在次线程中释放)中使用忙等待或互斥,当释放时,它会根据三元变量调用某些方法

//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

如果这是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.

在ActuCabror C++ +Builder中,有函数和函数,可以用来执行主线程中的函数。这可以从任何线程运行,它不必是
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)));
    }
}
#包括
#包括
名称空间{
类包装器:公共TppinerFacedObject{
公众:
包装器(std::函数f):f_f(f){}
void\uuu fastcall Invoke(){
f_u2;();
}
私人:
std::函数f;
};
const unsigned int main_thread=GetCurrentThreadId();
}//名称空间
//在主线程中异步执行函数
无效队列到主线程(std::函数f)
{
if(GetCurrentThreadId()==主线程){
f();
}
否则{
TThread::Queue(NULL,_di_TThread过程(新包装器(f));
}
}
//在主线程中同步执行函数
无效同步到主线程(std::函数f)
{
if(GetCurrentThreadId()==主线程){
f();
}
否则{
TThread::Synchronize(NULL,_di_TThread过程(新包装器(f));
}
}

很抱歉提出了一个蹩脚的问题,但如果这是一个控制台应用程序,该怎么办?akhisp只是想给出一个完整的答案,算是奖励。这没有错。我喜欢发送消息的方式。我将此方法应用于需要调用干扰UI的函数的内联挂接应用程序+1给你。对我来说可能有点难用。但至少它应该起作用。谢谢你能解释为什么哪个线程运行函数很重要吗?最好的方法在很大程度上取决于您试图解决的问题。嗯,有些函数执行时间很长,这会导致网络部分暂时无法处理下一个数据包。
如果在第三个线程中启动此函数,然后我让我的应用程序越来越难调试,因为有很多线程在运行,并且对列表、数组等做着奇怪的事情。\n\r(omg如果enter发送此注释,这里该如何换行)
因此我建议在主线程中执行此函数越容易检测代码中的错误,调试就越容易。增加代码的并发性将使bug更容易导致崩溃,从而减少查找和修复它们所需的时间。也许你在这一点上是对的。谢谢,我会考虑的