Как избежать блокировки (C ++, Win32) - PullRequest
1 голос
/ 18 марта 2009

Я делаю DLL, которая должна отвечать на запросы приложения. Одним из требований приложения является то, что вызов не должен занимать много времени для завершения.

Скажем, у меня есть функция foo (), которая вызывается хост-приложением:

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

Допустим, foo должен выполнить задачу (или вызвать функцию), которая наверняка займет много времени. Приложение позволяет мне установить переменную ожидания; если эта переменная отлична от нуля при возврате foo, она снова и снова вызывает foo (сбрасывает переменную ожидания перед каждым вызовом), пока не будет возвращено wait 0.

Какой лучший подход к этому?

Должен ли я идти:

int foo(arg){

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

    return 0;
}

Это на самом деле не решает проблему, которую для LengthyRoutine потребуется много времени. Должен ли я создавать какой-то поток, который обновляет inRoutine в зависимости от того, завершил ли он свою задачу?

Спасибо ..

Ответы [ 3 ]

7 голосов
/ 18 марта 2009

Создание другого потока - это почти лучший способ сделать это, просто убедитесь, что вы установили переменные результата, прежде чем установить переменную, которая говорит, что вы закончили, чтобы избежать условий гонки. Если это вызывается часто, вы можете заранее порождать рабочий поток и использовать его повторно, чтобы избежать накладных расходов на запуск потока.

Существует еще одно возможное решение: выполнять часть работы каждый раз, когда вызывается функция, однако это тратит больше времени в DLL и, вероятно, не оптимально, а также более сложно для реализации рабочего кода для большинства алгоритмов. .

1 голос
/ 18 марта 2009

Если программирование на C, используйте callback - передайте обратный вызов в foo. Вы должны договориться о подписи обратного вызова и выполнить некоторую служебную работу, чтобы активировать ее после завершения работы в LengthyRoutine.

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();
}

По существу Наблюдатель Шаблон в C. C ++ делает работу намного проще / чище, на мой взгляд

0 голосов
/ 18 марта 2009

Если невероятно редкая ситуация, когда LengthyRoutine() не является сторонним кодом, и у вас есть весь исходный код и его можно разбить на части, тогда вы можете рассмотреть возможность использования сопрограмм .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...