pvtest.php
2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
/*
* Zunächst mal den Gedanken skizziert
* Da es kein wirklich zuverlässiges Locking fuer kritische Bereiche
* in php gibt. Semaphore existiren nur unter Unix und flock arbeitet nicht
* wenn der webserver threaded ist und keine separaten prozesse pro
* request erzeugt habe ich folgenden Gedankengang...nicht 100% Atomar, aber
* möglicherweise das beste was man bekommen kann.
*
* ACQUIRE
* =======
* |
* - leere Datei erzeugen (tmp)
* - link (tmp) nach (lock)
* |
* |-----------------------------
* OK | | Fehler |
* | | |
* | | - lese (lock): sollte blockieren solange diese leer ist
* | | - unlink (lock)
* | | - link (tmp) nach (lock)
* | Fehler | |
* | ---------------|
* | | OK
* | |
* |-----------------------------
* |
* - (tmp) loeschen
* |
* (ENDE)
*
* RELEASE
* =======
* |
* - schreibe nach (lock)
* |
* (ENDE)
*
* Da link angeblick atomar ist muesste das zumindest zuverlaessig Sperren...
* Zusaettzlich sollte man vielleicht noch ein Priorisierung irgendwo
* festhalten, um zu verhindern das ein Prozess ewig wartet, weil er immer
* Pech bei der zuweisung von CPU Zeit hat.
*
* So ein Pech, read blockiert natuerlich nicht bei regulären Dateien, da
* ja EOF erreich wird....da muss ich mir was anderes ausdenken....
* OK, unter UNIX kann ich exec mkfifo machen um eine named pipe zu generieren.
* Fuer windows muss was anderes oder busy waiting (iiieeh) rein....
*
* !!! Zur info, schon der read open auf eine FIFO blocked wenn kein Writer
* existiert. Das war auch ein aspekt den man berücksichtigen muß... !!!
*/
function acquire ($lock, $tmp)
{
if (! file_exists ($tmp))
exec ('mkfifo ' . $tmp);
// hier koennte irgendwas bzgl. der Priorisierung in nem else folgen...
if (link ($tmp, $lock) === FALSE)
{
while (true)
{
$handle = fopen ($lock, 'w');
fwrite ($handel, '1');
fclose ($handle);
if (unlink ($lock) === FALSE) continue;
if (link ($tmp, $lock) === FALSE) continue;
break;
}
}
unlink ($tmp);
}
function release ($lock)
{
$handle = fopen ($lock, 'r');
stream_set_blocking ($handle, 0);
if (fread ($handle, 1) === 0)
unlink ($lock);
fclose ($handle);
}
acquire ('lock', 'tmp');
echo "Lock bekommen\n";
sleep (30);
release ('lock');
?>