Существует ли способ, которым я могу сделать два чтения атомарными?

Добавьте оператор использования перед определением класса.

use Illuminate\Http\Request;
use Auth; 
use App\Notifications\NewPost;

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

6
задан Dan Olson 10 April 2009 в 08:14
поделиться

4 ответа

Если вам действительно необходимо убедиться, что a и b не меняются во время выполнения этого теста, поэтому вам необходимо использовать одну и ту же синхронизацию для всех доступа к a и b . Это твой единственный выбор. Каждое чтение и каждая запись в любое из этих значений должны использовать один и тот же ограничитель памяти, синхронизатор, семафор, блокировку временного интервала или любой другой используемый механизм.

При этом вы можете убедиться, что если вы:

memory_fence_start();
int a = *MemoryLocationOne;
int b = *MemoryLocationTwo;
int test = (a + b) == 0;
memory_fence_stop();

return test;

, то a не изменится, пока вы читаете b . Но опять же Вы должны использовать один и тот же механизм синхронизации для всех доступа к a и к b .

Чтобы отразить последующее редактирование вашего вопроса, который вы ищете для метода без блокировок, это полностью зависит от процессора, который вы используете, и от того, как долго a и b и от того, являются ли эти области памяти последовательными и выровненными

Если предположить, что они последовательны в памяти и 32 бита каждый, и что ваш процессор имеет атомарное 64-битное чтение, то вы можете выполнить атомарное 64-битное чтение, чтобы прочитать два значения, проанализировать два значения из 64-битное значение, посчитайте и верните то, что вы хотите вернуть. Предполагая, что вам никогда не понадобится атомарное обновление для " a и b одновременно", но только для атомарных обновлений "

3
ответ дан 10 December 2019 в 00:44
поделиться

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

// all reads...
lock(lockProtectingAllAccessToMemoryOneAndTwo)
{
    a = *MemoryLocationOne;
    b = *MemoryLocationTwo;
}

...

// all writes...
lock(lockProtectingAllAccessToMemoryOneAndTwo)
{
    *MemoryLocationOne = someValue;
    *MemoryLocationTwo = someOtherValue;
}
3
ответ дан 10 December 2019 в 00:44
поделиться

Если вы ориентируетесь на x86, вы можете использовать 64-битную поддержку сравнения / обмена и упаковать оба целых числа в одно 64-битное слово.

В Windows вы сделал бы это:

// Skipping ensuring padding.
union Data
{
     struct members
     {
         int a;
         int b;
     };

     LONGLONG _64bitData;  
};

Data* data;


Data captured;

do
{
    captured = *data;
    int result = captured.members.a + captured.members.b;
} while (InterlockedCompareExchange64((LONGLONG*)&data->_64bitData,
                    captured._64BitData,
                    captured._64bitData) != captured._64BitData);

Действительно некрасиво. Я бы предложил использовать блокировку - гораздо более ремонтопригодную.

РЕДАКТИРОВАТЬ: Чтобы обновить и прочитать отдельные части:

data->members.a = 0;
fence();

data->members.b = 0;
fence();

int captured = data->members.a;

int captured = data->members.b;
3
ответ дан 10 December 2019 в 00:44
поделиться

Там действительно нет способа сделать это без блокировки. Насколько я знаю, ни у одного процессора нет двойного атомного чтения.

1
ответ дан 10 December 2019 в 00:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: