|
|||||||||||||||||||||||||||
Hejsa.
Jeg har et lille problem, som jeg ville høre, om der var nogen nem løsning på.
Problem: Jeg har et program, som laver nogle simulationer go spytter resultaterne ud i en fil. Denne fil vil
jeg læse med jævne mellemrum, for hvis et bestemt resultat er opnået behøver jeg ikke simulere flere gange,
og jeg kan afbryde det oprindelige program. En måde at løse dette var at sætte simulationsprogrammet over i
baggrunden (og få fingre i process ID'et) og så læse resultatfilen jævnligt. Hvis det kritiske resultat er
opnået inden simulaterne er kørt færdigt kan man så bare kill'e simulationsprocessen. Men ... i øjeblikket
benytter jeg denne stump kode:
sub RunAnalysis {
$file = shift;
$nPerm = shift;
# Simulationsprogrammet hedder pedipet
open(PP, "| pedipet ") || die "HOV! STOP!";
print PP "import\n";
print PP "$file\n";
# Lav en enkelt udregning
print PP "mixture\n";
# Så starter simulationerne
for (my $i= 0; $i<$nPerm; $i++) {
# Simuler nye data
print PP "sim geno 0\n";
# Idregn resultat
print PP "mixture\n";
# Check om dette resultat medførte kritisk værdi
last if (kritisk() == 1);
}
print PP "quit\n";
close(PP) || die "Problemer med pipen";
}
Funktionen kritisk() løver resultatfilen igennem og returnerer 1 hvis
simulationerne skal stoppe.
Problemet er jo bare, at ovennævnte program fylder input-bufferen til pedipet
op med $nPerm simulationer, og kritisk() bliver vurderet $nPerm gange inden resultatet
af den første simulation er blevet udregnet. Da pedipet er åbnet vha. en pipe er det først
med close(PP), at ovennævnte kode venter på at _alle_ simulationer er kørt. Det er ikke
hensigstmæssigt at starte pedipet-programmet op ved hver simulation (ellers var der ingen problemer),
da opstart og indlæsning af data tager lang tid.
Det jeg gerne ville var noget i stil med:
1) Udregn resultat på baggrund af oprindelige data
2) Simuler nye data
3) Lav udregninger
4) Hvis kritisk resultat så stop ellers gå til 2)
Simulationer tager forskellig tid så jeg vil helst undgå en sleep i for-løkken (og kan man så være sikker på at
pedipet så overhovedet har fået fyldt dens buffer op?). Kan man gøre det i ovenstående ramme eller er det
nemmere at
1) Sende alle kommandoerne til en fil
2) Start simulationerne med system("pedipet < runfile &");
3) Jævnligt checke resultatfilen
4) Hvis kritisk så stop.
Det eneste problem med nedenstående fremgangsmåde er, at man kan finde en let måde at få PID på
pedipet-programmet og ikke bare på den shell, der fyrer programmet af.
Mvh,
Claus
|
||||||||||||||
|
||||||||||||||