Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Podstawy C++ na Linuxie [Debian]

bohunmike 29 Maj 2012 11:25 3743 20
  • #1 29 Maj 2012 11:25
    bohunmike
    Poziom 12  

    Witam,

    Moje doświadczenie z programowaniem jest nikłe (proste programy w C i Javie pod Windą). Teraz przyszedł Linux i to jest udręka. Jako że miałem docelowo napisać program wykorzystujący funkcję fork (w domyśle miało to być drzewko procesów z wyświetlaniem PIDów). Jako że mi nie szło, spróbowałem od podstaw, ale też nie idzie, a więc do rzeczy:
    1. Zainstalowałem build-essentials.
    2. Mam g++ i gcc.
    3. Piszę prosty prog:

    Kod: bash
    Zaloguj się, aby zobaczyć kod

    4. Kompiluję go: gcc (lub g++) jakisplik.h -o jakisprog
    5. Nadaje uprawnienia chmod 777 jakisprog
    6. Próbuję uruchomić: ./jakisprog
    7. Błąd: bash: ./jakisprog: nie można uruchomić pliku binarnego
    8. A więc próbuję: sudo ./jakisprog
    9. Błąd: ./jakisprog: 1: Syntax error: word unexpected (expecting ")")
    10. Nie mam pomysłów, przeczytałem parę tematów na różnych forach i nie ma rozwiązania tego problemu, skończyły mi się pomysły, proszę o pomoc...

    Pozdrawiam

    0 20
  • #2 29 Maj 2012 11:48
    mickpr
    Poziom 39  

    bohunmike napisał:
    4. Kompiluję go: gcc (lub g++) jakisplik.h -o jakisprog
    Program w C powinien być w pliku z rozszerzeniem .c , .h to rozszerzenie nagłówków.
    W wyniku tej komendy powstanie plik OBJ. Nie ma on nic wspólnego z wykonywalnym (elf), jest plikiem wejściowym dla linkera (ld).
    bohunmike napisał:
    7. Błąd: bash: ./jakisprog: nie można uruchomić pliku binarnego

    Teraz już wiesz dlaczego.

    Spróbuj po prostu :
    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Polecam dowolne IDE - męczenie się samemu makefile-ami pozostawmy fascynatom.
    Na początek Geany - bardzo fajne środowisko. Ewentualnie Eclipse.

    Examples-ów do fork - pełno na Internecie np. http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html

    0
  • #3 29 Maj 2012 12:00
    michcior
    Poziom 30  

    mickpr napisał:
    Polecam dowolne IDE - męczenie się samemu makefile-ami pozostawmy fascynatom.
    Na początek Geany - bardzo fajne środowisko. Ewentualnie Eclipse.


    Nie zgadzam się, potem nie będzie wiedział o co chodzi. Takie IDE wszystko ukrywa, samo generuje makefile i całą masę innych rzeczy. Trzeba przerobić podstawy, no chyba że się nie chce być w tym dobrym to tak.

    Jazda obowiązkowa to gcc/g++, i makefile (GNU Makefile).
    Zadania:
    1) Kompilacja jednego pliku C, jak w tym przypadku
    2) Kompilacja wielu plików do obiektów, linkowanie jako oddzielny proces.
    3) Ustalanie ścieżki dla wyszukiwanie plików nagłówkowych
    4) Linkowanie z bibliotekami, systemowymi i innymi, ustawianie ścieżki wyszukiwania bibliotek
    5) Tworzenie biblioteki statycznej (archiwum .a) i dynamicznej (.so)
    6) Wykorzystanie makefile do zrobienia wszystkiego co powyżej, tworzenie plików zależności (tak by zmiana pliku .h powodowała kompilacje wszystkich zależnych .c/cc)

    Na albo pozostańmy przy IDE, w końcu trzeba nam coś robić do 67 roku życia :)

    0
  • #4 29 Maj 2012 12:14
    mickpr
    Poziom 39  

    michcior napisał:
    Nie zgadzam się, potem nie będzie wiedział o co chodzi. Takie IDE wszystko ukrywa, samo generuje makefile i całą masę innych rzeczy. Trzeba przerobić podstawy, no chyba że się nie chce być w tym dobrym to tak.

    Jazda obowiązkowa to gcc/g++, i makefile (GNU Makefile).
    Zadania:
    1) Kompilacja jednego pliku C, jak w tym przypadku
    2) Kompilacja wielu plików do obiektów, linkowanie jako oddzielny proces.
    3) Ustalanie ścieżki dla wyszukiwanie plików nagłówkowych
    4) Linkowanie z bibliotekami, systemowymi i innymi, ustawianie ścieżki wyszukiwania bibliotek
    5) Tworzenie biblioteki statycznej (archiwum .a) i dynamicznej (.so)
    6) Wykorzystanie makefile do zrobienia wszystkiego co powyżej, tworzenie plików zależności (tak by zmiana pliku .h powodowała kompilacje wszystkich zależnych .c/cc)


    Nie zasypuj kolegi 1000 tematami na raz, bo się przerazi i zostanie na Windows-ie. :(
    W obecnych czasach mało osób wie, co to assembler, jak generowany jest obraz TV - co pozostało starszemu pokoleniu, gdy w 64kB trzeba było upchnąć "cały ten zgiełk", kiedy za pomocą kartki i ołówka i opisu instrukcji Z80/6502 wyliczało się takty w krytycznych procedurach.

    Ja wiem, że nauka po łebkach na dłuższą metę do niczego nie prowadzi.
    Ale jak będzie miał chociażby dołączyć bibliotekę do swojego IDE - będzie musiał w końcu zajrzeć do Makefile. Nie od razu Kraków zbudowano.

    0
  • #5 29 Maj 2012 12:15
    bohunmike
    Poziom 12  

    Panowie rady bardzo pomocne, choć w sumie na programistę się szykuje (sieci i to w dodatku w najniższej warstwie - fizycznej), ale trochę muszę liznąć, a dobre praktyki najważniejsze.

    A więc wyniki:

    1. gcc nie działa:
    root@debian:/home/administrator/Pulpit# gcc qwe.c
    qwe.c:1:20: error: iostream: Nie ma takiego pliku ani katalogu
    qwe.c:3: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘namespace’
    qwe.c: In function ‘main’:
    qwe.c:8: error: ‘cout’ undeclared (first use in this function)
    qwe.c:8: error: (Each undeclared identifier is reported only once
    qwe.c:8: error: for each function it appears in.)
    qwe.c:8: error: ‘endl’ undeclared (first use in this function)

    2. g++ działa bez problemu

    A ktoś mi mówił (dużo osób) że rozszerzenia to tylko z rodziną Microsoft są ważne ?
    Mogę o słowo wyjaśnienia w tej sprawie ?

    0
  • #6 29 Maj 2012 12:17
    mickpr
    Poziom 39  

    Plik nagłówkowy z iostream nie jest elementem C, tylko C++ tak samo jak cout, endl 'for each' czy namespace.
    Poza tym program w C++ kończy się na '.cpp', nie na '.c'.

    Rozszerzenia nie są ważne - jeśli chodzi o wykonywanie plików.
    W windows plik wykonywalny ma rozszerzenie exe. W Unix - ma artybut wykonywalności , rozszerzenie nieistotne.

    0
  • #7 29 Maj 2012 12:24
    bohunmike
    Poziom 12  

    Jasne tu atrybut wykonywalności tam .exe. Wszystko ok i w końcu działa, pogrzebie jeszcze w tej mojej forkowej funkcji (mam zamiar troszkę to pozagnieżdżać), zobaczę co z tego wyjdzie, albo nie wyjdzie. Dzięki

    No już mam pierwsze pytanka:

    Mam już tak spreparowanego forka:

    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Daje to wynik:

    Kod: bash
    Zaloguj się, aby zobaczyć kod


    1. Skąd w drugiej linijce pojawia się treść promptu ?
    2. Jak oceniacie poprawność działania ?
    3. Czy mogę zobaczyć to w jakiś sposób w pstree ?

    Z góry dzięki.

    0
  • #8 29 Maj 2012 17:31
    krru
    Poziom 32  

    W procesie macierzystym PID potomka to wynik funkcji fork. getppid() da ci PID procesu powłoki.

    W printfach masz wywołania funkcji wewnątrz strinów - jako stałe napisowe.
    Chyba nie o to chodziło:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A o to:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #9 29 Maj 2012 17:34
    gaskoin
    Poziom 38  

    krru napisał:
    W procesie macierzystym PID potomka to wynik funkcji fork


    Proces macierzysty dostanie pid dziecka. Dziecko dostanie 0.
    Trochę się zakręciłem :D

    W ogóle program najpierw był częściowo w C++, a teraz już w nim nie jest w ogóle :) Ciekawe czym będzie gdy autor wrzuci go ponownie? Może w asemblerze?

    0
  • #10 29 Maj 2012 17:45
    mickpr
    Poziom 39  

    bohunmike napisał:
    ...
    Kod: bash
    Zaloguj się, aby zobaczyć kod

    Chyba źle stawiasz nawias - dlatego takie śmieci masz na wyjściu
    Powinno być w tym stylu:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    getpid() powinno być argumentem funkcji printf, a nie częścią ciągu, prawda?

    gaskoin napisał:
    W ogóle program najpierw był częściowo w C++, a teraz już w nim nie jest w ogóle :) Ciekawe czym będzie gdy autor wrzuci go ponownie? Może w asemblerze?

    Ja stawiam, że będzie jakiś fikuśny język: prolog, albo np. logo... :)

    0
  • #11 29 Maj 2012 17:47
    krru
    Poziom 32  

    bohunmike napisał:

    1. Skąd w drugiej linijce pojawia się treść promptu ?


    Z basha.
    Wieloprocesowość - główny proces powinien poczekać na zakończenie procesów potomnych.
    Jakiś wait() to robi.


    bohunmike napisał:

    3. Czy mogę zobaczyć to w jakiś sposób w pstree ?


    W tej wersji nie zdążysz.

    0
  • #12 29 Maj 2012 18:17
    bohunmike
    Poziom 12  

    Jeśli chodzi o assemblera to nie będzie na pewno, przerabiałem i nie moja bajka.... logo o to dawne czasy...haha. Panowie tak to jest jak coś się chcę a za bardzo się nie wie jak. Błędy poprawione, chodziło o to co napisaliście....

    Tylko teraz po wykonaniu żaden proces nie ma PID-u = 0, dlaczego ?

    Kod: bash
    Zaloguj się, aby zobaczyć kod


    Kolejna seria pytań ( na razie jedno):

    Jak mogę zrobić to aby zobaczyć procesy w pstree ?

    0
  • #13 29 Maj 2012 18:27
    mickpr
    Poziom 39  

    bohunmike napisał:
    Panowie tak to jest jak coś się
    chcę a za bardzo się nie wie jak. Błędy poprawione, chodziło o to co napisaliście....

    Zdrowe podejście - tak trzymać :)

    Co do pstree - ściągnij sobie źródła - już.
    To jest właśnie przewaga nad Windows - masz źródła, możesz sobie zajrzeć i sprawdzić.

    0
  • #14 29 Maj 2012 18:27
    gaskoin
    Poziom 38  

    Musiałbyś wstawić sleep(ileśtam), żeby zdążyć je zobaczyć, bo teraz to się program szybciej kończy niż naciśniesz cokolwiek :)

    0
  • #15 29 Maj 2012 18:41
    bohunmike
    Poziom 12  

    Panowie wspaniale po dodaniu sleepa widać już w pstree ładnie, zaraz zaczynam dalszą walkę...
    Pytań na razie nie mam, pewnie zaraz się zaczną (zaczynam zagnieżdżać...)...

    0
  • #16 29 Maj 2012 20:55
    krru
    Poziom 32  

    bohunmike napisał:

    Tylko teraz po wykonaniu żaden proces nie ma PID-u = 0, dlaczego ?


    Bo taka wartość nie jest przewidziana jako PID. Stąd wartość 0 jaką zwraca fork w procesie potomnym. Własny pid zawsze można sprawdzić getpid() a pid rodzica getppid().

    0
  • #17 29 Maj 2012 21:00
    gaskoin
    Poziom 38  

    PID 0 ma proces bezczynności, init ma PID 1. Generalnie te niskie PIDy są zarezerwowane dla sprzętu. Można sobie sprawdzić poleceniem top lub pstree -p.

    0
  • #18 30 Maj 2012 10:58
    bohunmike
    Poziom 12  

    Witam ponownie Panowie,

    A więc zmagań dzień 3, nadal próbuję okiełznać forka, lecz teraz w lekko bardziej
    zaawansowanej formie. Mianowicie chodzi mi, aby zagnieździć procesy według takiego
    schematu (w sumie to nie wiem czy tak się da). Przedstawiam go poniżej (przepraszam, za
    jakość - Paint):

    Podstawy C++ na Linuxie [Debian]

    Pomimo wielu prób nie udało mi się tego osiągnąć, a ostatnia kulturalnie wyglądająca
    forma prezentuje się tak (inne były, lecz rozrastały się w "kosmos"):


    Podstawy C++ na Linuxie [Debian]


    Czy jest szansa na zbudowanie schematu z pierwszego obrazka? Kod wygląda następująco (przepraszam za niechlujstwo, ale jest on ciągle modyfikowany):

    Kod: bash
    Zaloguj się, aby zobaczyć kod

    0
  • #19 30 Maj 2012 19:26
    krru
    Poziom 32  

    Tu już nie wystarczy rozróżnienie proces rodzicielski czy potomny - musisz wiedzić, którym procesem jesteś w tym grafie. Wystarczy pamiętać, że fork tworzy kopię aktualnego stanu procesu - razem w aktualnymi wartosciami wszystkich zmiennych. Wystarczy więc jedna zmienna odpowiednio ustawiana w powiązaniu z wynikiem forka i juz wiadomo w którym miejscu jesteśmy.

    0
  • #20 30 Maj 2012 22:16
    bohunmike
    Poziom 12  

    Jakoś nie bardzo to rozumiem, może jakiś mały przykład ?

    A jednak rada Kolegi stała się pomocna tylko spojrzałem na to z innej perspektywy...
    Teraz pytanie czy dobrze...

    A więc tak otrzymałem sobie taki obraz w pstree:

    Podstawy C++ na Linuxie [Debian]

    Czy jest on zgodny ze schematem zagnieżdżenia procesów który podawałem w poprzednim poście ?

    Chodzi mi głównie czy:

    Obrazek po lewo (to sam wyedytowałem) jest równy temu po prawo (ten z konsoli):

    Podstawy C++ na Linuxie [Debian]

    Dzięki i pozdro

    0
  • #21 10 Sty 2015 03:36
    bohunmike
    Poziom 12  

    Nikt nie odpowiedział, ale dałem radę, zadania z uczelni...

    0