Добре, първо, той е счупен. Просто имате късмет, че вашият компилатор е създал код, който случайно изглежда работи (или може би няма късмет, защото може да скрие фини грешки в ъглови случаи).
Открих, че всеки път, когато променливата се актуализира при обратно извикване, тя автоматично се актуализира в нишката, без да декларира променливата като 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