Добавьте оператор использования перед определением класса.
use Illuminate\Http\Request;
use Auth;
use App\Notifications\NewPost;
Я предполагаю, что вы создаете уведомление ремесленника, если нет, то имейте в виду, что пространство имен может быть другим.
Если вам действительно необходимо убедиться, что 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
одновременно", но только для атомарных обновлений "
Вы должны убедиться, что везде, где любое из двух значений было прочитано или записано, они были окружены барьером памяти (блокировка или критическая секция).
// all reads...
lock(lockProtectingAllAccessToMemoryOneAndTwo)
{
a = *MemoryLocationOne;
b = *MemoryLocationTwo;
}
...
// all writes...
lock(lockProtectingAllAccessToMemoryOneAndTwo)
{
*MemoryLocationOne = someValue;
*MemoryLocationTwo = someOtherValue;
}
Если вы ориентируетесь на 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;
Там действительно нет способа сделать это без блокировки. Насколько я знаю, ни у одного процессора нет двойного атомного чтения.