Noví Bulánci byli oficiálně vydáni. V roce 2021 bylo na Startovači na podporu vývoje této hry vybráno 7,3 miliónů Kč. Hra je zatím určena jenom pro Windows, díky Protonu ale běží také na Linuxu.
ChatGPT může vidět, slyšet a mluvit.
Upscaler je open source nástroj pro zvýšení rozlišení a vylepšení obrázků pomocí AI. Vývoj probíhá na GitLabu. Instalovat lze také z Flathubu. Stejně jako Upscayl je Upscaler postaven nad Real-ESRGAN.
GNUnet (Wikipedie) byl vydán v nové major verzi 0.20.0. Jedná se o framework pro decentralizované peer-to-peer síťování, na kterém je postavena řada aplikací.
V Dublinu o víkendu proběhla dvanáctá iterace multimediální konference Video Dev Days, kterou pravidelně pořádá nezisková organizace VideoLAN. Záznamy přednášek z prvního a druhého dne jsou dostupné na YouTube.
LibrePCB, tj. svobodný multiplatformní softwarový nástroj pro návrh desek plošných spojů (PCB), dospěl po pěti letech vývoje do verze 1.0.0. Přehled novinek v příspěvku na blogu a v aktualizované dokumentaci. Zdrojové kódy jsou k dispozici na GitHubu pod licencí GPLv3.
Facebook má nové logo. Poznáte rozdíl?
Byla vydána nová verze 7.2 v Javě napsané aplikace pro komplexní návrh rozmístění nábytku a dalšího vybavení v interiérech Sweet Home 3D. Vyzkoušet lze online verzi. Před dvěma týdny vyšla placená verze pro chytré telefony a tablety (App Store, Google Play).
Zítra 23. září proběhne Maker Faire Mladá Boleslav, festival plný workshopů, interaktivních činností a především nadšených a zvídavých lidí.
Byla vydána beta verze Ubuntu 23.10 s kódovým názvem Mantic Minotaur. Přehled novinek v poznámkách k vydání. Dle plánu by Ubuntu 23.10 mělo vyjít 12. října 2023.
n
procesov a aby kazdy potomok vypisal cislo od 0 po 4. Preco to ale nebezi naraz(paralelne?)
pid_t pid[n+1];
for(p = 0; p < n; p++)
{
pid[p] = fork();
switch(pid[p])
{
case -1:
/* fork error */
PANIC("fork");
break;
case 0:
child = true;
for(int i = 0; i < 5; i++) { printf("%d\n", i); fflush(stdout); }
break;
default:
waitpid(pid[p], NULL, 0);
child = false;
break;
}
if(child) break;
}
printf("--- (%d) => (%d)\n", getppid(), getpid());
Toto je vystup:
0
1
2
3
4
--- (12622) => (12623)
0
1
2
3
4
--- (12622) => (12624)
0
1
2
3
4
--- (12622) => (12625)
0
1
2
3
4
--- (12622) => (12626)
0
1
2
3
4
--- (12622) => (12627)
--- (3683) => (12622)
3683 je bash.
Dakujem za radu
Řešení dotazu:
default:
waitpid(pid[p], NULL, 0);
Ak tomu dobre rozumiem, tak sa hlavny proces najprv zdvoji (fork
),
a pocka waitpid
kym synovsky proces skonci.
A az potom pokracuje vo vykonavani cyklu
n
vlakien:
for(p = 0; p < n; p++)
{
pid[p] = fork();
switch(pid[p])
{
case -1:
/* fork error */
PANIC("fork");
break;
case 0:
child = true;
break;
default:
child = false;
break;
}
if(child) break;
}
if(child)
{
sleep(5);
//do_child_job(p);
}
if(parent)
{
for(p = 0; p < n; p++)
{
printf("parent\n");
waitpid(pid[p], NULL, 0);
}
Problem je vsak, ze ked napriklad 1. child proces nieco robi dlhsie, tak waitpid zablokuje hlavny proces cakanim na skoncenie a az potom sa zavola waitpid na dalsie procesy. Comu ale uz vobec nerozumiem, preco sa tento kod sprava tak, ze da takyto vystup:
parent // tu caka tych 5 sekund
parent // dalsie 4 riadky uz vypise okamzite
parent
parent
parent
Slo by asi pouzit WNOHANG
vo waitpid namiesto 0
, ale potom hlavny proces skonci a nepocka na skoncenie deti.
Ako teda zabezpecit, ze hlavny proces nebude blokovany child procesmy, ale zaroven pocka, kym vsetky skoncia?
static void sigchld_hdl(int sig)
{
running_children--;
printf("sigchld_hdl\n"); fflush(stdout);
/* Wait for all dead processes.
* We use a non-blocking call to be sure this signal handler will not
* block if a child was cleaned up in another part of the program. */
while (waitpid(-1, NULL, WNOHANG) > 0)
{
}
if(running_children == 0) // toto je vlastne na upratanie po detoch, ked uz vsetky su skoncene
{
printf("--QUITING\n"); fflush(stdout);
fclose(fp);
if (msgctl(msqid, IPC_RMID, NULL) == -1)
PANIC("msgctl");
exit(EXIT_SUCCESS);
}
}
potom v main()
struct sigaction act;
memset (&act, 0, sizeof(act));
act.sa_handler = sigchld_hdl;
if (sigaction(SIGCHLD, &act, 0)) {
perror ("sigaction");
return 1;
}
for(p = 0; p < n; p++)
{
pid[p] = fork();
switch(pid[p])
{
case -1:
/* fork error */
PANIC("fork");
break;
case 0:
child = true;
break;
default:
child = false;
running_children++;
printf("adding child: %ld\n", running_children); fflush(stdout);
break;
}
if(child) break;
}
if(child)
{
printf("(%d) cakam...\n", getpid()); fflush(stdout);
msg_rcv(READY_TO_START);
printf("(%d) child\n", getpid()); fflush(stdout);
exit(EXIT_SUCCESS);
// sleep(1);
}
if(parent)
{
for(p = 0; p < n; p++)
{
printf("parent\n"); fflush(stdout);
waitpid(pid[p], NULL, WNOHANG);//WNOHANG
msg_snd(READY_TO_START, READY_TO_START_TRUE);
}
while (running_children>0) {
sleep(1);
printf("sleeping, running children: %ld\n", running_children); fflush(stdout);
}
}
Toto teda vacsinou funguje, avsak niekedy sa to zasekne na tom poslednom while(running_children>0) a vystup je takyto:
$ ./philosophers 5
(26467) >> sending message(1): 1
(26467) >> sending message(2): 0
adding child: 1
(26468) cakam...
adding child: 2
(26469) cakam...
adding child: 3
(26470) cakam...
adding child: 4
(26471) cakam...
adding child: 5
parent
(26467) >> sending message(3): 0
parent
(26468) >> receiving message(3): 0
(26468) child
(26469) >> receiving message(3): 0
(26469) child
sigchld_hdl
(26467) >> sending message(3): 0
parent
(26467) >> sending message(3): 0
parent
(26470) >> receiving message(3): 0
(26470) child
(26471) >> receiving message(3): 0
(26471) child
(26472) cakam...
sigchld_hdl
(26467) >> sending message(3): 0
parent
(26467) >> sending message(3): 0
(26472) >> receiving message(3): 0
(26472) child
sigchld_hdl
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
sleeping, running children: 2
^C
Chape to niekto?
Dakujem
Problém už byl vyřešen, ale neodpustím si terminologickou poznámku:
Nasledujuci kod spusti pekne n vlakien:
Syscall fork()
nevytváří vlákna ale procesy. Vlákna by se vytvářela pomocí pthread_create()
.
Tiskni
Sdílej: