On Sat, Oct 24, 2009 at 04:33:28PM +0300, Martin Kolev wrote: > Здравейте, > > Искам първо да вметна, че не съм програмист и ползвам BASH от дъжд на вятър, > т.е. пълен лаик. > > Ето и какво ме накара да пиша тук: > Реших с помощта на rrdtool да чертая графика на прихванатите вируси от > антивирусната ми програма. За целта си направих един "прост" BASH скрипт, > който се изпълнява с помощта на procmail, когато се прихване вирус от > антивирусната програма, като целта му е да увеличава с единица стойността на > едно число - индекс: > > > #!/bin/bash > > virusvar=`/bin/cat /etc/rrdtool/mail/virus-count` > ((virusvar++)) > /bin/echo -n $virusvar > /etc/rrdtool/virus/virus-count > > Всичко си сработва много добре, но когато сървъра се натовари (т.к. си е бая > стар и е с много малко RAM памет) поредността на числото, което се записва > във virus-count се обърква. Прави ми впечатление, че това се случва в > момент, когато е натоварен и четенето/писането от и във virus-count става в > почти един и същи момент. > > Много съм любопитен да разбера защо се случва това?
Стандартен случай на нужда от синхронизация при едновременен достъп до общ ресурс - често се среща, има готови решения. Накратко, това, което се случва, е, че може да получиш няколко такива съобщения почти едновременно и програмката ти да се изпълни няколко пъти, преди първите да са свършили съвсем. Тъй като цялото изпълнение на един шел-скрипт е доста сложна операция, особено когато се изпълняват и външни програми, напълно е възможно не само да бъдат пуснати няколко такива "едновременно", ами и да си прехвърлят топката по време на изпълнение - да се изпълни някаква част от първия, после някаква част от втория, после пак някаква част от първия, после малко от третия и т.н. Пример: 1. Идва съобщение А, стартира се скриптът за него (да кажем "скрипт А") 2. Скрипт А чете virus-count, прочита стойност 510 3. Идва съобщение Б, стартира се скриптът за него (да каем "скрипт Б") 4. Скрипт Б чете virus-count, *и той прочита 510* 5. Скрипт А увеличава 510 с 1, получава 511, записва 511 във virus-count 6. Скрипт Б увеличава 510 с 1, получава 511, записва 511 във virus-count Ако тръгнат да се изпълняват едновременно три копия на скриптчето, може да се получат даже по-забавни неща, като virus-count от 510 да стане първо 511, после 512 и накрая пак 511 :) Решението при съвременните Unix-системи е просто - има програмка, която понякога се казва "lockfile", друг път "flock", и се изпълнява по леко различни начини, но идеята й е да създаде специален файл и тогава да изпълни твоята програма - особеното е, че ако специалният файл вече съществува или вече е заключен, lockfile чака, докато другият го отключи. По този начин, тъй като lockfile заключва файла, изпълнява твоята програма и после отключва файла, е на практика сигурно, че твоята програма няма да бъде изпълнена два пъти едновременно. Опитай през procmail да пускаш твоето скриптче не направо, а през lockfile с някакво избрано от теб име на файл: lockfile /var/lock/virus-count /usr/bin/increase-virus-count ...където /usr/bin/increase-virus-count е твоето скриптче. Поздрави, Петър -- Peter Pentchev [email protected] [email protected] [email protected] PGP key: http://people.FreeBSD.org/~roam/roam.key.asc Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553 This sentence would be seven words long if it were six words shorter.
pgp9U9Nw8l5wP.pgp
Description: PGP signature
_______________________________________________ Lug-bg mailing list [email protected] http://linux-bulgaria.org/mailman/listinfo/lug-bg
