Требуется ли синхронизация при передаче флага отмены с помощью P / Invoke? - PullRequest
0 голосов
/ 31 мая 2019

Я передаю флаг отмены по ссылке (или по указателю) в C ++ DLL с помощью P / Invoke. Флаг будет установлен в какое-то время в коде C #, а код C ++ проверяет его и возвращает, когда флаг установлен. Нужно ли где-нибудь делать синхронизацию?

Поскольку код C ++ читает флаг, в то время как код C # пишет флаг, присутствует гонка данных. «Эффективный современный C ++» рекомендует использовать std :: atomic для параллелизма, чтобы избежать проблем гонки данных, но он недоступен в ситуации P / Invoke. Я думаю, что флаг должен быть определен как volatile, чтобы компилятор C ++ не оптимизировал флаг чтения из отмены, но мне сказали, что volatile не следует использовать в ситуациях параллелизма.

Функция C ++ выглядит следующим образом:

void doSomething(int &cancelFlag) {
    while (true) {
        ...
        if (cancelFlag != 0) {
            return;
        }
    }
}

Обновление: код C # похож на следующий. И я обнаружил, что «canCancel» - это еще одна гонка данных.

// token is a CancellationToken
IntPtr cancelFlag = Marshal.AllocHGlobal(Marshal.SizeOf<int>());
Marshal.WriteInt32(cancelFlag, 0);
bool canCancel = true;
token.Register(() =>
{
    if (canCancel)
    {
        Marshal.WriteInt32(cancelFlag, 1);
    }
});

doSomething(cancelFlag);
canCancel = false;
Marshal.FreeHGlobal(cancelFlag);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...