Re: [Lug-bg] Bash gimnastiki
- Subject: Re: [Lug-bg] Bash gimnastiki
- From: Peter Pentchev <roam@xxxxxxxxxxx>
- Date: Sat, 24 Oct 2009 18:04:32 +0300
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 roam@xxxxxxxxxxx roam@xxxxxxxx roam@xxxxxxxxxxx
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.
Attachment:
pgpRNtW7NpFVY.pgp
Description: PGP signature
_______________________________________________
Lug-bg mailing list
Lug-bg@xxxxxxxxxxxxxxxxxx
http://linux-bulgaria.org/mailman/listinfo/lug-bg
|