» »

[C] in delo s procesi v Linuxu

[C] in delo s procesi v Linuxu

Greek ::

Imam sledeče navodilo naloge:

Napišite program, ki ustvari n novih sinov, ki se izvajajo vzporedno.
n podamo kot argument programa. V kolikor argumenta ne podamo, program izpiše navodila za uporabo.
Nadalje prvi sin ustvari 1 nov proces, drugi 2 nova procesa, ..., n-ti (n) novih procesov.
Vsi vnuki oziroma procesi drugega nivoja, se izvajajo vzporedno.
Za pravilno delovanje programa mora vsak oče v drevesni strukturi procesov počakati, da
izvajanje končajo vsi njegovi sinovi.
Vsak novo ustvarjen proces izpiše svoj PID in PPID.

Sedaj zadevo sem naredil, kot mislim da je prav, a nisem prepričan, da je zagotovo prav, zato bom vas tu vprašal.
Recimo za izpis z argumentom n=3 mam tako:

Proces: 1, PID: 2583, PPID 2582
Proces: 1, PID: 2584, PPID 2583
Proces: 2, PID: 2585, PPID 2582
Proces: 2, PID: 2586, PPID 2585
Proces: 2, PID: 2587, PPID 2585
Proces: 3, PID: 2588, PPID 2582
Proces: 3, PID: 2589, PPID 2588
Proces: 3, PID: 2590, PPID 2588
Proces: 3, PID: 2591, PPID 2588

Za n=6 pa tako:

Proces: 1, PID: 2649, PPID 2648
Proces: 1, PID: 2650, PPID 2649
Proces: 2, PID: 2651, PPID 2648
Proces: 2, PID: 2652, PPID 2651
Proces: 2, PID: 2653, PPID 2651
Proces: 3, PID: 2654, PPID 2648
Proces: 3, PID: 2655, PPID 2654
Proces: 3, PID: 2656, PPID 2654
Proces: 3, PID: 2657, PPID 2654
Proces: 4, PID: 2658, PPID 2648
Proces: 4, PID: 2659, PPID 2658
Proces: 4, PID: 2662, PPID 2658
Proces: 4, PID: 2660, PPID 2658
Proces: 4, PID: 2661, PPID 2658
Proces: 5, PID: 2663, PPID 2648
Proces: 5, PID: 2664, PPID 2663
Proces: 5, PID: 2665, PPID 2663
Proces: 5, PID: 2666, PPID 2663
Proces: 6, PID: 2667, PPID 2648
Proces: 6, PID: 2668, PPID 2667
Proces: 6, PID: 2669, PPID 2667
Proces: 6, PID: 2670, PPID 2667
Proces: 5, PID: 2671, PPID 2663
Proces: 5, PID: 2672, PPID 2663
Proces: 6, PID: 2673, PPID 2667
Proces: 6, PID: 2674, PPID 2667
Proces: 6, PID: 2675, PPID 2667


Sinovi in Vnuki se tvorijo, to se vidi po tem, da se v vnukov PPID prenese PID Sina (oz njihovega očeta), ni mi pa zdaj čist jasno ali so sinovi vzporedni in tudi vnuki vzporedni ali so zaporedni?? Sklepam oz mislim, da bi se vzporedno takrat navodila naloge uresničila, če bi najprej izpisalo za n procesov po vrsti (Proces 1 PID 1234, Proces 2 PID 1235, Proces 3 PID 1236 itd...) in za tem vnuki (Proces 1 PID 5678 PPID 1234, Proces 2 PID 5679 PPID 1235, Proces 2 PID 5680 PPID 1235 itd)... Kako je sedaj dejansko prav?

Hvala vnaprej!
  • spremenil: Greek ()

BigWhale ::

Ce uporabljas fork() potem tecejo vzporedno. Drugace ne morejo. :)

Jean-Paul ::

Če ne veš, da imaš prav, potem verjetno nimaš prav :). Naloga zahteva, da se morajo vsi procesi izvajati istočasno. To lahko preveriš tako, da v vnuke daš en sleep(60) in potem z ukazom

pstree -p PID

pogledaš, če je temu res tako. Prilepi izpis, ki ga dobiš pri n=3

P.S. PID zamenjaš s pid-om očeta.

Greek ::

Ce uporabljas fork() potem tecejo vzporedno. Drugace ne morejo. :)


Ah to pa ne drži! Odvisno kako sprogramiraš. Če daš zaključevanje (wait(0)) izven for zanke tečejo vzporedno, če znotraj for zanke, delaš s procesi zaporedno. Tu pa imam pač težavo, ker je potrebno, da se izvajajo sinovi vzporedno, nato še pa vnuki vzporedno!

Recimo en primer, ki sem ga delal z vzporednimi/zaporednimi procesi je rekurzivno računanje fibonnacijevega stevila, kjer prvi sin zracuna n-1 člen, drugi n-2 člen itd... Če imaš zaporedno sprogramirano, bo program čakal, da se izračuna največje število, nato bo šel v drugega sina in čakal da se izračuna drugo največje število itd... Če pa imaš vzporedno, pa se za procesor dovol velike obremenitve (torej večja števila) izračunajo kasneje, manjša pa prej ;)...

Greek ::

Če ne veš, da imaš prav, potem verjetno nimaš prav :). Naloga zahteva, da se morajo vsi procesi izvajati istočasno. To lahko preveriš tako, da v vnuke daš en sleep(60) in potem z ukazom

pstree -p PID

pogledaš, če je temu res tako. Prilepi izpis, ki ga dobiš pri n=3

P.S. PID zamenjaš s pid-om očeta.


Če dam sleep v vnuke, pride izpis pri n=3 takole:

Proces: 1, PID: 2661, PPID 2660
Proces: 2, PID: 2663, PPID 2660
Proces: 3, PID: 2666, PPID 2660
Proces: 1, PID: 2662, PPID 2661
Proces: 2, PID: 2664, PPID 2663
Proces: 2, PID: 2665, PPID 2663
Proces: 3, PID: 2667, PPID 2666
Proces: 3, PID: 2668, PPID 2666
Proces: 3, PID: 2669, PPID 2666

Oni ukaz pa mi ne izpiše nič :|... Še vedno pa sem v dvomih. A nebi moralo biti tako, da bi imeli prvi trije izpisi (torej sini oz procesi 1. nivoja) zaporedni PID v tem primeru naloge? In potem spet vnuki (oz. procesi 2. nivoja) spet zaporedne pide? Sini in vnuki se tvorijo vredu, to vidimo po PPIDih vnukov, le vprašanje ali se izvajajo vzporedno ali zaporedno :)?

Jean-Paul ::

Na vrstni red izpisov se ne zanašaj. Nikoli ne veš, kateri proces pride prej na vrsto, če za to ne poskrbiš s sinhronizacijo. Pomembno je, da tečejo vsi hkrati in da vsak oče počaka sinove, da se zaključijo.

Zakaj ti pstree -p PID ne izpiše nič? Pognati ga moraš še preden se procesi zaključijo (zato obvezno daj sleep v vnuke). PID moraš zamenjati s pid-om tvojega očeta (v zgornjem primeru bi bil to 2660). Če ti pstree -p 2660 ne izpiše nič, pomeni, da je proces 2660 že mrtev, kar ni pravilno.

Primer izpisa za n=3:
$ pstree -p 5681
fork(5681)-+-fork(5682)---fork(5684)
           |-fork(5683)-+-fork(5685)
           |            `-fork(5686)
           `-fork(5687)-+-fork(5688)
                        |-fork(5689)
                        `-fork(5690)

Zgodovina sprememb…

Greek ::

Ne, ukaz pstree -p "PID očeta" se ne odziva.

Jean-Paul ::

Kaj pomeni, da se ne odziva? Ga imaš nameščenega? Kaj se zgodi, če poženeš pstree brez argumentov?

Greek ::

Brez argumentov mi deluje vredu.

Jean-Paul ::

Poglej na ZS

BigWhale ::

Ce uporabljas fork() potem tecejo vzporedno. Drugace ne morejo. :)


Ah to pa ne drži! Odvisno kako sprogramiraš. Če daš zaključevanje (wait(0)) izven for zanke tečejo vzporedno, če znotraj for zanke, delaš s procesi zaporedno. Tu pa imam pač težavo, ker je potrebno, da se izvajajo sinovi vzporedno, nato še pa vnuki vzporedno!


Cim ti izvedes fork() ti vsaj dva procesa teceta vzporedno. Tukaj ni debate.

Ce eden potem caka drugega niti ni pomembno, se vedno teceta dva procesa.

OmegaM ::

Pozdravljeni.

Bi kar nadaljeval v tej temi, ker imam z razumevanjem le tega.

Namrec vem da z fork() kreiram oz. mi izvede vsaj 2 procesa (PID-a).

Ampak nečesa vseeno vredu ne razumem.

Kateri proces je sedaj prvi oz. kateri je oče in kateri sin.
Vem kaj pomeni PID - proces ID, PPID - parent proces ID.

Vem da se neumno slisi, vendar verjetno mesam kljub temu, da tam pise parent.

Nato imam drugo vprasanje.
Namrec imam preprost primercek

#include <stdio.h>
#include <unistd.h>

int main () {
	printf("PID:%d; PPID:%d\n", getpid(), getppid());
	return 0;
}


Ko ta primer pozenem mi izpise PID: 2631; PPID: 2234

Če uporabim ukaz pstree -p 2234 mi vrne rezultat bash(2234)----pstree(2651), če uporabim recimo pstree -p 2631 mi ne vrne nič, torej pomeni to, da je oče PID 2234.
Ni mi pa jasno zakaj ne izpise 2631.

Drugi del vprasanja pa se recimo nanaša na kreiranje z fork().


#include <stdio.h>
#include <unistd.h>

int main () 
{
        fork();
	printf("PID:%d; PPID:%d\n", getpid(), getppid());
	return 0;
}


In ko spet zaženem svoj primer mi lepo izpise stiri vrednosti.
Te so:
PID: 2659; PPID: 2234
PID: 2660; PPID: 2659

Torej sem kreiral nov proces, in tu me muči vprašanje:
1. Ali ko sem kreiral z fork() nov proces, ali sem aktiviral proces za bash ali kateri proces?
2. Ko znova uporabim ukaz pstree -p 2234 mi izpise bash(2234)----pstree(2661), kaj tocno to spet pomeni? Da je Oče PPID: 2234, 2661 pa ....?

HVala.

Se opravicujem za ta vprasanja, ampak upam na razumljiv odgovor, ker na spletu nekako meni razumljive zadeve ne odkrijem.

Hvala
Ni nam lahko, bo pa boljše!!!

BigWhale ::

Tale tvoj program se prehitro izvede in zakljuci, da bi ga lahko videl s pstree. Daj notri sleep() za tisti printf() in potem uporabi pstree ukaz v drugem terminalu.

Potem bo tudi pstree deloval 'pravilno', torej bo vrnil rezultat, kot si ga ti zelis. :) Ko izvedes fork() se na tistem mestu naredi se en proces, ki tece od tam naprej. Prejsnji proces pa izvajanje nadaljuje.

Tvoj drugi primer to lepo pokaza. Prvi printf() vrne ven pid trenutnega procesa in pa parent procesa, ki je v tem primeru lupina bash. Drugi prinf() pa pride od tistega forkanega procesa. Tukaj je ppid pid, ki ga je dobil tvoj proces, ko si pognal program.

2234 bash
+
+-- 2659 tvoj program
  +
  +-- 2660 drugi proces tvojega programa, po klicu fork().


Takole nekako zgleda.

OmegaM ::

Hvala BW.

Imam se eno vprasanje.

Namrec ne vem, ce delam v redu, zato me prosim popravi.

Imam namrec nalogo s katero bi rad ... ce citiram na hitro ...

... prvi sin ustvari 1 nov proces, drugi 2 nova procesa, ..., n-ti (n) novih procesov.
Vsi vnuki oziroma procesi drugega nivoja, se izvajajo zaporedno....


mene pa sedaj zanima, če sem se vredi lotil tega.

Tu se nahaja del kode:
for(i=1;i<=n1;i++)
{
   fork();
   printf("PID:%d; PPID:%d; %d\n", getpid(), getppid(), (int)pow(n2,i));
   wait();
}


Če sta n1=2 && n2=3 pri zaporednem izvajanju bi veljalo torej fork(), WAIT,fork(),WAIT ...


Nekako pa mi ni uspelo wait "nastavit".

Hvala
Ni nam lahko, bo pa boljše!!!

Zgodovina sprememb…

  • spremenilo: OmegaM ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Baterije za slušne aparate.

Oddelek: Pomoč in nasveti
73765 (3675) drekodovce
»

Sestava Mining Rig-a

Oddelek: Pomoč in nasveti
83569 (3094) Invictus
»

c++ fork()

Oddelek: Programiranje
61377 (693) Randomness
»

LibreSSL za zdaj še nevaren

Oddelek: Novice / Varnost
177381 (5995) AndrejO
»

[C] Procesi

Oddelek: Programiranje
6969 (878) Cvenemir

Več podobnih tem