Автор Гілка: TCP, демони, масштабовані сервера та інше...  (Прочитано 5690 раз)

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Хочеться трішки розібратись із програмуванням на С цих речей, тобто обмін по TCP, як демони пишуться і як взагалі зробити масштабований сервер. Якби десь хоч одним оком глянути на джереліни тексти якогось простенького чат-серверу (ми щось таке під вікна на лабах по сі в інститурі робити)  чи що, бо боюсь що в текстах апача я буду розбиратись ну дуже довго.......

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Демон зробити дуже просто. Ось програмка, яка запускає будь яку команду як демон:
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  int exitCode=0;
  exitCode=daemon(0,0);
    
  if(exitCode!=0){
    exit(exitCode);
  }
    
 exitCode=execv(argv[1], argv+1);
 
 exit(exitCode);
}
[Fedora Linux]

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Дякую,
по програмування сокетів я ось це знайшов. Мені підходить

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Щось я незовсім розумію як працює fork(), З AfxBeginThread якось зрозуміліше було,,,,

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
вроді з самим fork'ом все зрозуміло, незрозуміло як ним користуватись

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Якщо fork() == 0, то виконання у породженому процесі, якщо fork()>0, то це PID породженого процесу, якщо fork() <0, то сталася помилка.
[Fedora Linux]

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Це я прочитав і зрозумів. От тільки не збагну як цим користуватись. Ось по аналогії із тим-же AfxBeginThread мені наприклад потрібно запустити якусь функцію у паралель із тим, хто її запускає. тобто є пойнтер на функцію, як запустити її в паралелі і далі продовжувати займатись своїми справами?

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Це я прочитав і зрозумів. От тільки не збагну як цим користуватись. Ось по аналогії із тим-же AfxBeginThread мені наприклад потрібно запустити якусь функцію у паралель із тим, хто її запускає. тобто є пойнтер на функцію, як запустити її в паралелі і далі продовжувати займатись своїми справами?

І батьківський процес і нащадок продовжують роботу з того ж місця - з наступної після fork() команди. Не потрібно ніякої додаткової точки входу.

[Fedora Linux]

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Нащадок - точна копія батька, тобто код нащадка і батька це один і той же код, так ? Я зовсім неможу зрозуміти як цим користуватись.
Ну от, якщо почати з самого почаку, в певний момент під час запуску системи ядро виконує fork() для того щоб запустити init, створюється процес із PID=1 який виконує init, алже цей процес є копією процесу ядра із PID=0, тоді код процесу із PID=0 мусить містити код запуску init але не викокувати його, а пропустти. Відповідно код процесу із PID=1 містить власне той-же fork() який його ж породив і все інше але тільки повинен запустити init. Далі процес init починає створювати нові процеси, які є копією його ж але ж він в свою чергу є копією процесу із PID=0. отже всі інші процеси в деякій свої частині є копіями процесу із PID=0 і всіх своїх батьків. Я все правильно зрозумів ? Де тоді логіка ?
« Змінено: 2007-10-15 21:29:07 від vano_vvv »

Відсутній DalekiyObriy

  • Літератор
  • ******
  • дописів: 1929
  • Карма: +5/-0
логіка тут полягає у технології copy-on-write: коли виконується fork в багатьох випадках (демон) новий процес є тим самим, що і запускаюча його програма, тому коли запускаюча програма виходить лишається лише демон у фоновому режимі...
а якщо скажімо ядро робить fork() і потім exec() при запуску exec() (і лише на ньому) створюється новий прості процеса, після цього ядро і init вже не пов’язані, оскільки exec() повністю заміщує процес, що його викликав...

тобто хитрість в тому, що власне на сам fork() нічого великого не робиться, лише створюється новий контекст процесу, що в останніх ядрах процес надшвидкий...

схема трішки заплутана для нового погляду, але математично бездоганна і є історично випробувана...

І насправді основних варіантів вживання два:
1. fork() і потім викликальник виходить а нащадок стає демоном...
2. fork() і потім exec*() тоді процес-викликальник працює, як працював, а другий (нащадок) повністю замінюється програмою з exec*()
« Змінено: 2007-10-15 23:10:46 від DalekiyObriy »
Fedora 35 (x86-64)

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
Приклад то зрозумілий але чи неможна було від'єднатись від потоків вводу/виводу без виклику fork()  і отримати такий-же результат ?

А якщо я захочу зробити багатопотокову програму де власне різні потоки повинні виконувати різні функції тоді як?  всі мої потоки будуть копіями один одного, писати здоровенний switch ? але тоді код інших функцій, які даний конкретний породжений поток не виконує,  буде висіти  пам'яті  багато разів. exec запустить нову програму із іншого файлу чи є інші варіанти ?

і ще, знову ж таки процес викликальник містить виклик функції exec() але сам її не виконує

PS: власно про fork() є розписано, а от як ним правильно, чисто алгоритмічно, користуватись я щось не знайшов.

PPS теоретично то все зрозуміло а от із практикою важче,,,,
« Змінено: 2007-10-15 23:53:18 від vano_vvv »

Відсутній DalekiyObriy

  • Літератор
  • ******
  • дописів: 1929
  • Карма: +5/-0
Приклад то зрозумілий але чи неможна було від'єднатись від потоків вводу/виводу без виклику fork()  і отримати такий-же результат ?
теоретично можна, але тоді демон не віддасть керування, тобто закривання потоків не означає повернення керування...
тобто ви робите
$ ./mydaemon
і чекаєте поки він не зробить exit()
а власне, очікування від даемону є те, що він віддає керування і відгалуджується у фон

А якщо я захочу зробити багатопотокову програму де власне різні потоки повинні виконувати різні функції тоді як?  
man pthread_create
(на рівні системи - це теж fork() але з іншими прапорцми і це від програмера приховано)

і ще, знову ж таки процес викликальник містить виклик функції exec() але сам її не виконує
на відміну від вінди, в Unix exec() виконує програму, але не повертає керування (якщо немає помилки), тобто єдиний спосіб запустити нову програму паралельно до старої: fork() + exec()

PS: власно про fork() є розписано, а от як ним правильно, чисто алгоритмічно, користуватись я щось не знайшов.
це залежить від того, що Ви збираєтесь робити: відгалузити програму у фон (демоном), запустити нову програму паралельно чи запустити багато потоків всередині програми...
Fedora 35 (x86-64)

Відсутній vanessa

  • Графоман
  • ****
  • дописів: 468
  • Карма: +0/-0
 
man pthread_create
(на рівні системи - це теж fork() але з іншими прапорцми і це від програмера приховано)
О!!!! це те що мені наданий момент потрібно :) дуже дяую,