кодът работи добре без непостоянен?

Здравейте, наскоро написах код със следния скелет:

variable;

callback(){
//variable updated here
}

thread_function(){
//variable used
}

main(){
//callback registered
//thread registered
}

Открих, че всеки път, когато variable се актуализира при обратно извикване, той автоматично се актуализира в нишката, без да се декларира variable като volatile. добре, не ми е ясно как се управлява. Благодаря ви предварително. между, callback() се извиква от библиотека, която се компилира с кода.


person Akhil    schedule 01.10.2015    source източник
comment
Възможен дубликат на C++ Едновременна модификация и четене на единична глобална променлива   -  person Maxim Egorushkin    schedule 01.10.2015
comment
Този C въпрос не може да бъде дубликат на C++ въпрос. Двата езика се опитват да координират официалната си многонишкова семантика, но те неизбежно са определени малко по-различно.   -  person Potatoswatter    schedule 01.10.2015
comment
Възможен дубликат на Защо е необходим volatile в C?   -  person Bo Persson    schedule 01.10.2015


Отговори (1)


Добре, първо, той е счупен. Просто имате късмет, че вашият компилатор е създал код, който случайно изглежда работи (или може би няма късмет, защото може да скрие фини грешки в ъглови случаи).

Открих, че всеки път, когато променливата се актуализира при обратно извикване, тя автоматично се актуализира в нишката, без да декларира променливата като volatile. добре, не ми е ясно как се управлява.

Започвайки от тук: това е една и съща променлива. Нишките споделят едно и също адресно пространство. Така че това е, което наивно бихте очаквали.

volatile е за оптимизации. C компилаторът е свободен да направи много модификации на вашия код, за да го направи по-бърз, това включва пренареждане на изрази, нечетене на достъпна променлива, тъй като същата стойност е в регистър, дори "развиване" на цикли и много повече. Обикновено единственото ограничение е, че наблюдаваното поведение остава същото (google за това, не искам да пиша книга тук.)

Четенето на променлива от нормална памет не създава никакви странични ефекти, така че може законно да бъде пропусната без промяна на поведението. C (преди c11) не знае за нишки . Ако дадена променлива не е записана в някаква част от кода, се приема, че съдържа същата стойност, както преди.

Сега, това, което volatile ви дава, е да каже на компилатора, че това не е нормална памет, а място, което може да се промени извън контрола на вашата програма (като например I/O регистър, картографиран в паметта). С volatile компилаторът е длъжен действително да извлече променливата за всяка операция за четене и действително да я съхрани за всяка операция за запис. Също така не е позволено да пренареждате достъпите между няколко volatile променливи. Но това е всичко и не е достатъчно за синхронизиране на нишки. За това също се нуждаете от гаранцията, че никакви други достъпи до паметта или изпълнение на код не се пренареждат около достъпите до вашата променлива, дори и при многопроцесорни процесори -> имате нужда от бариера на паметта.

Забележете, че това е различно от напр. java, където volatile ви дава това, от което се нуждаете за синхронизиране на нишки . В c използвайте това, което библиотеката pthreads ви дава: мутекси, семафори и условни променливи.

tl;dr

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

person Community    schedule 01.10.2015
comment
volatile за теми е грешно -- Не е ли малко преувеличено? Мисля, че в много прости случаи можете да се измъкнете само с volatile променливи, за да сигнализирате нещо от една нишка към друга. - person undur_gongor; 01.10.2015
comment
Не, винаги е грешно. Той въвежда гаранции, от които не се нуждаете, като същевременно пропуска важните. Да, с volatile можете да сте сигурни, че евентуално във вашия код, промяната ще бъде забелязана. Не получавате точна синхронизация. Просто го направете както трябва във всеки случай... - person ; 01.10.2015
comment
@undur_gongor Предлагам такива строги правила, защото е 1.) трудно да се каже със сигурност дали един небрежен волатил тук и там наистина ще свърши работа във вашия случай и 2.) създават кодиране на лоши навици и в крайна сметка дават грешни идеи за това какво прави volatile в C. - person ; 01.10.2015