Высокоточные синхронизированные операции с многопроцессорным приложением на Windows / C ++ - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть несколько процессов (которые находятся в разных исполняемых файлах, созданных подпроектами), созданных моей основной программой.

То, что я хочу сделать, - это запускать каждый процесс в течение примерно 1-2 миллисекунд в каждом главном кадре 40-50 миллисекунд.Когда я использую поток приостановки / возобновления для приостановки одного процесса (путем приостановки всех потоков, которые у него есть, но у каждого есть только один.) И возобновления следующего, только один контекст переключения (приостановить старый и возобновить новый) длится около 60 миллисекунд.Который длиннее даже моего основного кадра.Кстати, я знаю, что использование Sleep не рекомендуется в этой манере, так как единственная операция сна / пробуждения длится 15-30 мс, и я не использую ее.

Если я изменю приоритет запущенного процесса на более низкий, а следующий процесс - на более высокий;гарантируется ли переключение контекста окнами в течение микросекунд?или что я должен рассмотреть, чтобы достигнуть только микросекундного чувствительного переключения процесса?И мне интересно, сколько времени обычно занимает простая операция Suspend / ResumeThread?

В настоящее время я не могу использовать потоки, встроенные в процессы, поскольку мне нужна изоляция памяти процесса, и мои процессы могут порождать и завершать свои собственные потоки.Дает ли Waithandlers, как методы синхронизации, точное время?мс и дает вам мс).Мне нужно использовать QueryPerformanceCounter и другие способы достижения высокого разрешения, как я уже упоминал.

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

Для очень высокой точности можно использовать следующую функцию:

void get_clock(LONGLONG* SYSTEM_TIME)
{
    static REAL64 multiplier = 1.0;
    static BOOL alreadyCalculated = FALSE;

    if (alreadyCalculated == FALSE)
    {
        LARGE_INTEGER frequency;
        BOOL result = QueryPerformanceFrequency(&frequency);
        if (result == TRUE)
        {
            multiplier = 1000000000.0 / frequency.QuadPart;
        }
        else
        {
            DWORD error = GetLastError();
        }
        alreadyCalculated = TRUE;
   }

    LARGE_INTEGER time;
    QueryPerformanceCounter(&time);

    *SYSTEM_TIME = static_cast<SYSTEM_TIME_TYPE>(time.QuadPart * multiplier);
}

В моем случае объекты синхронизации не очень хорошо подходят (однако я использовал их там, где время не критично), вместо этого я имеюпереработал мою логику для размещения заполнителей там, где поток должен был выполнить действие, и вычислил время, используя приведенную выше функцию.

Но все еще не уверен, приходит ли задача с более высоким приоритетом, сколько времени занимает окно, чтобы перенести его в процессор и выгрузитьработает один.

0 голосов
/ 20 сентября 2018

Как говорит Реми, вы должны делать это с объектами синхронизации - вот для чего они.Предположим, что процесс A выполняется первым и хочет «передать» процесс B в какой-то момент.Затем он может сделать это:

SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE };
HANDLE hHandOffToA = CreateEventW (&sa, TRUE, FALSE, L"HandOffToA");
HANDLE hHandOffToB = CreateEventW (&sa, TRUE, FALSE, L"HandOffToB");

// Start process B
CreateProcess (...);

while (!quit)
{
    // Do work, and then:
    SetEvent (hHandOffToB);
    WaitForSingleObject (hHandOffToA, INFINITE);
}

CloseHandle (hHandOffToA);
CloseHandle (hHandOffToB);

И тогда процесс B может сделать:

HANDLE hHandOffToA = OpenEventW (EVENT_MODIFY_STATE, FALSE, L"HandoffToA");
HANDLE hHandOffToB = OpenEventW (SYNCHRONIZE, FALSE, L"HandoffToB");

while (!quit)    
{
    WaitForSingleObject (hHandOffToB, INFINITE);
    // Do work, and then:
    SetEvent (hHandOffToA);
}

CloseHandle (hHandOffToA);
CloseHandle (hHandOffToB);

Вы, конечно, должны включить надлежащую проверку ошибок, и я оставил это на ваше усмотрениерешить, как процесс A должен сказать процессу B завершить работу (я полагаю, он может просто его убить).Помните также, что имена событий являются общесистемными, поэтому выбирайте их более тщательно, чем я.

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