|> Здравейте, | |Драсти, | |> Искам първо да вметна, че не съм програмист и ползвам 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 става в почти един и същи момент. |> |> Много съм любопитен да разбера защо се случва това? | |Накратко, както обяси и Пенчев, твоя скрипт не е reentrant, |т.е. не е здравословно за се влиза в него докато предното му |изпълнение не е приключило защото има споделен ресурс, т.е. |файла и цялата операция става неопределена. | |Ето ти още две решения: | |1) брутално: procmail вика mktemp който създава празни файлове |с уникални имена в дадена директория и ти ги бройкаш от време |на време - нямам споделен ресурс, няма да хаби дисково |пространство, и едва ли ше удариш лимита по брой файлове на |файловата система ;-) | |2) чрез signal handlers (фнимателно със signal handlers, да са |много леки) |http://www.gnu.org/software/libc/manual/html_node/Nonreentrancy |.html#Nonreentrancy | |компилираш следната програмка: | |#include <stdio.h> |#include <stdlib.h> |#include <signal.h> | |/* This variable is set by the SIGALRM signal handler. */ |volatile sig_atomic_t flag = 0; |/* Ugly global counter */ |volatile long c = 0; | |void print_event() { | fprintf(stdout, "%ld\n", c); |}; | |void register_event() { | ++c; |}; | |int main (void) |{ | signal(SIGALRM, register_event); | signal(SIGUSR1, print_event); | | sigset_t block_alarm; | /* Initialize the signal mask. */ | sigemptyset (&block_alarm); | sigaddset (&block_alarm, SIGALRM); | | while (1) { | /* Check if a signal has arrived; if so, reset |the flag. */ | sigprocmask (SIG_BLOCK, &block_alarm, NULL); | if (flag) | flag = 0; | | sigprocmask (SIG_UNBLOCK, &block_alarm, NULL); | } |} | | |Казваш на procmail да й праща SIGALRM с kill -s когато дойде |вирус (това е доста по-бързо от отваряне и писане във файл;-), |а ти можеш да я тестваш за дуракоустойчивост така, ако |приемем, че се казва a.out: | |пращаш бройка сигнали (все едно пратени от procmail): |for a in `seq 1 100`; do kill -s SIGALRM `pidof a.out`; done | |питаш я колко са получени: |kill -s SIGUSR1 `pidof a.out` | |(трябва да е стартирана разбира се и пише на stdout) | |-- |pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>
Много Ви благодаря за подробните разяснения. Реших да ползвам mktemp и в момента всичко си сработва. Поздрави и лека работа! Мартин Колев _______________________________________________ Lug-bg mailing list [email protected] http://linux-bulgaria.org/mailman/listinfo/lug-bg
