В вашем вопросе вы спросили о регулярном выражении, и я большой поклонник и пользователь из них, поэтому, когда мне нужно было сделать такой же аргумент, как и вы, я написал свое собственное регулярное выражение после того, как искал его и не нашел простого решения , Мне нравятся короткие решения, поэтому я сделал один, и вот он:
var re = @"\G(""((""""|[^""])+)""|(\S+)) *";
var ms = Regex.Matches(CmdLine, re);
var list = ms.Cast<Match>()
.Select(m => Regex.Replace(
m.Groups[2].Success
? m.Groups[2].Value
: m.Groups[4].Value, @"""""", @"""")).ToArray();
Он обрабатывает пробелы и кавычки внутри кавычек и преобразует закрытые «" в ". Не стесняйтесь использовать код!
http://en.cppreference.com/w/cpp/atomic/memory_order имеет хороший пример внизу , который работает только с memory_order_seq_cst
. По существу, memory_order_acq_rel
обеспечивает порядок чтения и записи относительно атомарной переменной, в то время как memory_order_seq_cst
обеспечивает порядок чтения и записи глобально. То есть последовательно согласованные операции видны во всех потоках в одном и том же порядке.
Пример сводится к следующему:
bool x= false;
bool y= false;
int z= 0;
a() { x= true; }
b() { y= true; }
c() { while (!x); if (y) z++; }
d() { while (!y); if (x) z++; }
// kick off a, b, c, d, join all threads
assert(z!=0);
Операции над z
защищены двумя атомными переменными, а не одной, поэтому вы не можете использовать семантику acqu-release для принудительного выполнения этого z
всегда увеличивается.
По-прежнему использовать определение и пример из memory_order . Но замените memory_order_seq_cst на memory_order_release в магазине и memory_order_acquire при загрузке.
Упорядочение Release-Acquire гарантирует все, что происходило до того, как хранилище в одном потоке становится видимым побочным эффектом в потоке, который выполнил загрузку. Но в нашем примере ничего не происходит до того, как сохранит как в thread0, так и в thread1.
x.store(true, std::memory_order_release); // thread0
y.store(true, std::memory_order_release); // thread1
Более того, без memory_order_seq_cst последовательное упорядочение thread2 и thread3 не гарантируется. Вы можете представить, что они становятся:
if (y.load(std::memory_order_acquire)) { ++z; } // thread2, load y first
while (!x.load(std::memory_order_acquire)); // and then, load x
if (x.load(std::memory_order_acquire)) { ++z; } // thread3, load x first
while (!y.load(std::memory_order_acquire)); // and then, load y
Итак, если thread2 и thread3 выполняются до thread0 и thread1, это означает, что x и y остаются ложными, таким образом, ++ z никогда не затрагивается, z остается 0 и Утверждает огонь.
Однако, если memory_order_seq_cst входит в изображение, он устанавливает единый общий порядок изменения всех атомарных операций, которые так помечены. Таким образом, в thread2 x.load затем y.load; в thread3, y.load, а затем x.load - это точно.
На ISAs как x86, где карта атомной энергетики к барьерам и фактическая модель машины включают буфер хранилища:
seq_cst
хранилища требуют сбрасывания буфера хранилища, таким образом, более поздние чтения этого потока задержаны, пока хранилище не глобально видимо. acq_rel
делает не , сбрасывают буфер хранилища. Нормальные загрузки x86 и хранилища имеют по существу acq и семантика рэла. (seq_cst плюс хранилище буферизуют с передачей хранилища.)
, Но x86 атомарные операции RMW всегда продвигаются на seq_cst
, потому что префикс x86 asm lock
является полным барьером памяти. Другой ISAs может сделать ослабленный или acq_rel RMWs в asm.
https://preshing.com/20120515/memory-reordering-caught-in-the-act является поучительным примером различия между хранилищем seq_cst и простым хранилищем выпуска. (Это на самом деле mov
+ mfence
по сравнению с плоскостью mov
в x86 asm. На практике xchg
более эффективный способ сделать хранилище seq_cst на большинстве x86 центральных процессоров, но GCC действительно использует mov
+ mfence
)
Забавный факт: инструкция хранилища выпуска AARCH64 STLR на самом деле последовательна - выпуск. В аппаратных средствах это имеет загрузки/хранилища с расслабленным или seq_cst и барьерами для получения других преимуществ. Но к сожалению я думаю, рэл или acq_rel должны быть усилены к seq_cst, потому что нет никакого барьера или инструкции, которая дает все rel
потребности, не будучи еще более сильной и более дорогой. Некоторые другие ISAs (как PowerPC) имеют больше вариантов барьеров и могут усилиться [до 1 111] или mo_acq_rel
более дешево, чем [1 113].