Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności: PyStok #39, 20 marca 18:00, Białystok: AI w diagnostyce obrazowej i metaklasy
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: fork()  (Przeczytany 1368 razy)
« : 18:29 21/11/18 »
robin Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 21


Mam taki przykład z Programming Python 4
Kod
import os
 
parm = 0
while True:
      parm += 1
      pid = os.fork()
      if pid == 0:
           os.execlp('python', 'python', 'child.py', str(parm))
           assert False, 'error starting program'
      else:
           print('Child is', pid)
           if input() == 'q': break
 

A output wygląda tak

Kod
Child is 4556
Hello from child 4556 1
 
Child is 5920
Hello from child 5920 2
 
Child is 316
Hello from child 316 3
q
 

Teraz pytanie jest takie, jak kolejny child łapie rosnący parm ? Bo przecież gdy robi kolejny niezależny proces w fork to robi od nowa kod i przypisuje mu wartość 0 i dodaje jeden.
Zapisane
« Odpowiedz #1 : 04:13 22/11/18 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 64
Płeć: Mężczyzna
Wiadomości: 467


To jest w sumie dość proste Uśmiech.
On buduje od nowa kod, ale nie tego pliku który wywołujesz, tylko child.py
Załóżmy że child.py ma taką treść:
Kod
arg = 0
arg += 1
print('child:' arg)
Wtedy widać jak na dłoni, że twój child jest wykonywany zawsze od początku.
A twój plik main, tylko go odpala, przez co tutaj w pętli while, parm nie jest budowany od zera, jest do niego dodawana wciąż jedynka w pętli while, jest ciągle inkrementowany aż do zakończenia programu main/wyjścia z pętli while.
Przykład wyjścia:
Kod:
Child is 15303
child: 1

Child is 15304
child: 1

Child is 15305
child: 1
q


------------------
(program exited with code: 0)
Press return to continue
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
« Odpowiedz #2 : 15:12 22/11/18 »
robin Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 21


Jest to trochę nieintuicyjne. Jeżeli dobrze rozumiem jak łączy się fork z exec to powstaje coś innego niż zwykły fork , który sam zawsze tworzy sam z siebie nowy proces. I jak już jesteśmy w fork to nie tworzy kolejny call do fork() tylko child.
Ale może w sumie będzie to lepiej wytłumaczone w kolejnych rozdziałach książki.  Co?

Kod
 os.execlp('python', 'python', 'child.py', str(parm))

A wie ktoś dlaczego w komendzie trzeba dwa razy wpisać python ?
Zapisane
« Odpowiedz #3 : 12:42 12/02/19 »
robin Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 21


Sorrki że odświeżam temat. Może mi ktoś wyjaśnić czemu w pythonie kod który stosuje funkcje z UNIXA jest taki dziwny i różny od normalnego ? Co można zrobić by go ogarniać ?
Zapisane
« Odpowiedz #4 : 14:00 12/02/19 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 64
Płeć: Mężczyzna
Wiadomości: 467


Chyba nie do końca rozumiem pytanie @robin Uśmiech.
Może nie jestem na czasie, ale forkowanie (Czyli tworzenie procesów potomnych) jest również używane w Windowsie/MacOS/BSD* przez menadżera procesów.
https://en.wikipedia.org/wiki/Fork_(system_call)

Chyba że pytasz o coś innego niż forkowanie Uśmiech
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
« Odpowiedz #5 : 14:52 12/02/19 »
robin Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 21


Np to ,że kod jest taki dziwny nie pythonowy. Nie ma takiego control flow jak normalny pythonowy kod. Np funkcja select albo fork. z exec.  W tym przykładzie co dałem wcześniej , gdyby nie os.execlp . to normalny kod powinien nastawiać perm na zero.

Albo w tym przykładzie co dałem teraz z select(). Jak for ma przeszukiwać nad readables gdy socket staje się gotowy gdy odbierze połączenie za pomocą accept() który jest przecież wcięty w for ?




Kod
# event loop: listen and multiplex until server process killed
print('select-server loop starting')
while True:
   readables, writeables, exceptions = select(readsocks, writesocks, [])
   for sockobj in readables:
       print(readables)
       if sockobj in mainsocks:
           newsock, address = sockobj.accept()
           print('Connect:', address, id(newsock))
           readsocks.append(newsock)
       else:
           data = sockobj.recv(1024)
           print('\tgot', data, 'on', id(sockobj))
           print('\tgot', data, 'on', id(sockobj))
           if not data:
               sockobj.close()
               readsocks.remove(sockobj)
           else:
               reply = 'Echo=>%s at %s' % (data, now())
               sockobj.send(reply.encode())
 

  



  

Zapisane
« Odpowiedz #6 : 16:42 12/02/19 »
cezio Offline
Advanced Python User

Zobacz profil
**

Reputacja: 32
Wiadomości: 111


Cytuj
Np to ,że kod jest taki dziwny nie pythonowy. Nie ma takiego control flow jak normalny pythonowy kod. Np funkcja select albo fork. z exec.  W tym przykładzie co dałem wcześniej , gdyby nie os.execlp . to normalny kod powinien nastawiać perm na zero.

Bo funkcje pythonowe są wrapperami na wywołania z libc, nazwy i parametry są zbliżone do, albo wręcz skopiowane ze źródłowego API. W C typ musi być znany na etapie kompilacji, więc jest kilka wariacji wywołania w zależności od parametrów, patrz: http://man7.org/linux/man-pages/man3/exec.3.html
Nie ma też wyjątków, więc często trzeba sprawdzać ręcznie czy funkcja zwróciła błąd.
Dobrze jest zajrzeć do manuala takich funkcji, bo pythonowa dokumentacja nie zawiera wszystkich szczegółów.

Niektóre grupy wywołań mają bardziej przystępne wrappery wyższego poziomu, gdzie masz podejście obiektowe, np. threading albo subprocess (wrappery na pthread i exec*).

Cytuj
A wie ktoś dlaczego w komendzie trzeba dwa razy wpisać python ?

A to akurat ciekawe, aż musiałem sprawdzić. Wyszło na to, że drugi i kolejne argumenty są przekazywane bezpośrednio do sys.argv:

https://stackoverflow.com/questions/13439938/execlp-in-python
Zapisane
« Odpowiedz #7 : 17:22 12/02/19 »
robin Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 21


Czyli mówisz żeby to ogarniał to muszę ogarniać co nieco język C i jądra UNIXA  Szok ?
Funkcję select będzie musiał chyba zastąpić jakiś frameworkiem jak np asyncore. Bo za nic nie rozumiem tego kodu.
Zapisane
« Odpowiedz #8 : 17:30 12/02/19 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 64
Płeć: Mężczyzna
Wiadomości: 467


Wszystko zależy od twoich potrzeb, do wyboru masz masę narzędzi, kwestia tylko tego co dla ciebie lepiej się sprawdzi:
`Async, Threating, Submodule, Fork, Subprocess` to tylko część z narzędzi.
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2019 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot