简体   繁体   English

如何避免阻塞(C++、Win32)

[英]How to avoid blocking (C++, Win32)

I'm making a dll that has to respond to an application's requests.我正在制作一个必须响应应用程序请求的 dll。 One of the application's requirements is that a call should not take long to complete.应用程序的要求之一是调用不应花费很长时间才能完成。

Say, I have a function foo(), which is called by the host application:比如说,我有一个 function foo(),它由主机应用程序调用:

int foo(arg){
    // some code i need to execute, say,
    LengthyRoutine();
    return 0;
}

Lets say, foo has to perform a task (or call a function) that is certain to take a long time.可以说, foo 必须执行肯定需要很长时间的任务(或调用函数)。 The application allows me to set a wait variable;该应用程序允许我设置一个等待变量; if this variable is non-zero when foo returns, it calls foo again and again (resetting the wait variable before each call) until wait is returned 0.如果 foo 返回时此变量非零,它会一次又一次地调用 foo(在每次调用之前重置等待变量),直到等待返回 0。

What's the best approach to this?最好的方法是什么?

Do I go:我做 go:

int foo(arg){

    if (inRoutine == TRUE) {
        wait = 1;
        return 0;
    } else {
        if (doRoutine == TRUE) {
             LengthyRoutine();
             return 0;
        }
    }

    return 0;
}

This doesn't really solve the problem that LengthyRoutine is gonna take a long time to complete.这并不能真正解决 LongyRoutine 需要很长时间才能完成的问题。 Should I spawn a thread of some sort that updates inRoutine depending on whether or not it has finished its task?我是否应该根据它是否完成任务来生成某种类型的线程来更新 inRoutine?

Thanks..谢谢..

Spawning another thread is pretty much the best way to do it, just make sure you set the result variables before you set the variable that says you're finished to avoid race conditions.产生另一个线程几乎是最好的方法,只需确保在设置表示您已完成的变量之前设置结果变量以避免竞争条件。 If this is called often you might want to spawn a worker thread ahead of time and reuse it to avoid thread start overhead.如果经常调用它,您可能希望提前生成一个工作线程并重用它以避免线程启动开销。

There is another possible solution, do part of the work each time the function is called, however this spends more time in the DLL and probably isn't optimal, as well as being more complex to implement the worker code for most algos.还有另一种可能的解决方案,每次调用 function 时都做部分工作,但是这会在 DLL 中花费更多时间,并且可能不是最佳的,而且对于大多数算法来说实现工作代码也更加复杂。

If C programming, use callback - pass the callback to foo.如果 C 编程,使用回调 - 将回调传递给 foo。 You have to agree on the callback signature and do some housekeeping to trigger it when the work in LengthyRoutine is done.您必须就回调签名达成一致,并在 LongyRoutine 中的工作完成时进行一些内务处理以触发它。

typedef (void) callbackFunction(void);

int foo(arg, callbackFunction)
{
   // some code i need to execute, say,
   // register callback and return right away
   // Trigger the LengthyRoutine to run after this function returns

   return 0;
}

LengthyRoutine()
{
   // do lenghty routine

   // now inform the caller with their suppiled callback
   callbackFunction();
}

Essentially Observer Pattern in C.本质上是 C 中的观察者模式。 C++ makes the work a lot easier/cleaner in my opinion C++ 在我看来让工作变得更容易/更干净

If incredible rare situation where LengthyRoutine() isn't 3rd party code and you have all the source and it's possible to split it up then you can consider using coroutines .如果LengthyRoutine()不是 3rd 方代码并且您拥有所有源代码并且可以将其拆分的难以置信的罕见情况,那么您可以考虑使用coroutines

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM