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_Sendmessage - Fatal编程技术网

C++ C+中的跨线程操作+;没有发送消息

C++ C+中的跨线程操作+;没有发送消息,c++,multithreading,sendmessage,C++,Multithreading,Sendmessage,我正在寻找一种按照SendMessage允许的方式执行跨线程操作的方法。换句话说,如何让一个线程在另一个线程中执行某些函数。但是我想在没有SendMessage的情况下完成它,因为这需要一个并不总是可用的窗口 同步或异步都可以 .NET是通过System.Windows.Threading.Dispatcher类实现的,所以肯定有办法吗?所以我猜我们在这里讨论的是Windows操作系统,对吗?你应该在你的问题中具体说明这一点。例如,Windows解决方案可能与Linux解决方案不同 现在,关于您

我正在寻找一种按照SendMessage允许的方式执行跨线程操作的方法。换句话说,如何让一个线程在另一个线程中执行某些函数。但是我想在没有SendMessage的情况下完成它,因为这需要一个并不总是可用的窗口

同步或异步都可以


.NET是通过System.Windows.Threading.Dispatcher类实现的,所以肯定有办法吗?

所以我猜我们在这里讨论的是Windows操作系统,对吗?你应该在你的问题中具体说明这一点。例如,Windows解决方案可能与Linux解决方案不同

现在,关于您的问题,对于这种情况的任何解决方案都将迫使您的线程要么等待某个事件发生(使任务排队),要么无休止地轮询某个任务

所以我们讨论的是某种互斥,一个条件变量,或者一些特殊的睡眠函数

向其他线程发送“任务”的一种(简单)且不可移植的方法是使用内置的Win32机制
APC
AsynchronouspprocedureCall)

它利用了这些功能,我已经在我的Windows 10+Visual studio 2015上对该解决方案进行了小型测试

namespace details {
    void waitforTask() noexcept {
        SleepEx(INFINITE, TRUE);
    }

    void __stdcall executeTask(ULONG_PTR ptr) {
        if (ptr == 0) {
            return;
        }
        std::unique_ptr<std::function<void()>> scopedPtr(reinterpret_cast<std::function<void()>*>(ptr));
        (*scopedPtr)();
    }
}

template<class F, class ... Args>
void sendTask(void* threadHandle, F&& f, Args&& ... args) {
    auto task =
        std::make_unique<std::function<void()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));

    const auto res = QueueUserAPC(&details::executeTask,
        threadHandle,
        reinterpret_cast<ULONG_PTR>(task.get()));
    if (res == 0) {
        throw std::runtime_error("sendTask failed.");
    }

    task.release();
}
名称空间详细信息{
void waitforTask()不例外{
SleepEx(无限,真实);
}
void uu stdcall executeTask(ULONG_PTR PTR){
如果(ptr==0){
返回;
}
std::unique_ptr scopedPtr(重新解释强制转换(ptr));
(*DPTR)();
}
}
模板
void sendTask(void*threadHandle,F&&F,Args&&…Args){
自动任务=
std::make_unique(std::bind(std::forward(f)、std::forward(args)…);
const auto res=QueueUserAPC(&details::executeTask),
丝柄,
重新解释(task.get());
如果(res==0){
抛出std::runtime_错误(“sendTask失败”);
}
task.release();
}
示例用法:

std::thread thread([] {
        for (;;) {
            details::waitforTask();
        }
    });

   sendTask(thread.native_handle(), [](auto literal) {
        std::cout << literal;
   }, "hello world");
std::线程线程([]{
对于(;;){
详细信息::waitforTask();
}
});
sendTask(thread.native_handle(),[](自动文字){

std::您是否需要一个工作队列,目标线程在处理其项时被卡住,这正是
Dispatcher
类在.NET中提供的。我需要使用什么函数?我正在查看“线程池API”文档,但它似乎只能对特殊工作线程上的操作进行排队。如果工作线程需要对主UI线程上的操作进行排队,该怎么办?对于不习惯本机Windows开发的人来说,这似乎很奇怪,但拥有不可见的窗口是非常常见的。在许多情况下,即使线程从未运行过,也需要一个窗口显示单个用户可见的元素,这是完全可以接受的。因此,如果必须交换或侦听消息,只需创建一个窗口。虽然解释实际问题可能是一个好主意,但很少需要在特定线程上执行某些操作。如果有UI线程,请使用SendMessage,只需创建消息即可ow并将其用于跨线程业务。@MatteoItalia好的,那么你从哪里得到我想要劫持另一个线程的消息?我问的正是这些函数的功能,而我不知道QueueUserAPC似乎是最佳选择。问题解决了。谢谢,QueueUserAPC正是我需要的。你知道是否存在同步等价物吗ent?在此上下文中定义同步。那么,基本上,您希望线程A将任务排队到线程B,然后等待线程B完成任务?我不理解这个问题。在您执行其他任务时,让另一个线程执行某项任务是(一个)Asynchronous的定义以SendMessage的方式为例,它等待窗口过程处理消息,然后返回。这也是Dispatcher.Invoke和Dispatcher.BeginInvoke方法之间的区别。@user1610015这是一件非常糟糕的事情。如果必须使线程卡住,请向您添加win32事件函数,并使函数在函数结束时设置该事件。然后在队列线程中等待该事件。同样,这忽略了异步代码的全部要点。