ПредишенСледващото

Това съдържание е част от поредицата: Един пример за развитието на една проста многонишков уеб сървър

Останете на линия за предстоящите статии в тази серия.

След проучване в предишната част на цикъла с организацията на мрежови връзки през TCP логически да мисли за отговора на програмата на исканията на мрежата. На сегашния етап на развитие на технологични подходи, както обикновено, няколко, които ни позволява да се създаде гъвкава програма, в добра степен на предназначението и товара. Традиционно, има по-добър подход, има значение за всеки отделен случай. Налични начини да отговори на входящи заявки могат да се комбинират, например, в един такъв списък:

  • "Просто" се справят с настоящата молба и да се върнете в очакване на нова заявка;
  • хвърлят хайвера си нов процес и да го давате за обработка на заявката; се върнете към чакащите;
  • генериране на нова нишка (нишката) и го прехвърли за обработка на искането; се върнете към чакащите;
  • Тя може да доведе до множество процеси или нишки предварително и да ги "няколко", и при обработката на превода искане на една от тях и се върна в очакване;
  • могат да се използват произволни комбинации от вградени процеси, в които се генерират от множество процеси, съдържащи множество нишки.

лесна обработка

Най-простият вариант - нищо, за да се генерира и обработва искането за контекста на един и същ процес (или поток), в който исканията на чакащите. От гледна точка на програмен подход е изключително проста, но и с много проста, гъвкава и неефективни при тежък товар.

Когато заявките идват по-често от програмното време, за да ги обработи, а след това те трябва да се изчака реда си. Ако всички заявки е по-дълъг от една определена стойност, тогава ядрото ще изхвърли новопристигналите искания. Ясно е, че в система с един процесор с едноядрен процесор паралелно извършване на процеса за генериране / нишка може радикално да се подобри положението, защото процесор, и така през повечето време е заета от изпълнението на кода на нашата програма. Въпреки това, наличието на многоядрен процесор и / или мулти-процесорни системи е разликата между проста преработка и паралелизирано няма да бъде в полза на един прост вариант, тъй като в този случай ще бъдат активно използвани само един процесор (или едно ядро), както и всички други ще бъдат активни.

лечение мулти-процес

В този случай, след получаване на искането, генерирана от друг процес (който е копие на настоящия процес, който получи искане), и където се извършва обработката. Това се извършва, например, така че (има само илюстрация на възможен подход):

Новият процес се генерира с помощта на вилка (2). В този случай, няма нужда от нещо, което да е изрично премине поколението, защото по време на поколение потомък на копие от родителя (във връзка с това се справят "размножават"). След успешното поколение потомък на новата връзка в контекста на родителя, можете да затворите и да се върнете към чака следващия. Преди това, в контекста на родителя стои като нещо, което да се помни ID (PID) процес на дете до по-късно, след приключването му, този идентификатор може да премахнете информацията приключи потомък на процесите на масата, за да се избегне задръстват си сергия и дейности в процеса на първоначален система. Как точно знаем за потомък на завършване?

Когато състоянието на процеса на дете (спряно, възобновено или завършено) изпраща ядро ​​родител SIGCHLD сигнал, който може да бъде обработена в рамките на родител и да предприеме съответните действия. обработка на сигнала трябва да бъде включено изрично, защото тя се игнорира по подразбиране. При пристигане на сигнала може да се стартира заобикаляйки списък спаси PID потомци за всяка причина, например, waitpid функция (2) в не-блокиране на готовност, и погледнете в резултата. Можете да избегнете този списък изброяване на родителите на деца (преди прекратяване) PID този потомък чрез някой от методите на IPC (Интер Process Communication) - канал (тръба), гнездо файл или razdelyamuyu паметта на. В този случай, това е "възможност" да получи няколко PID получената почти едновременно завършване на множество потомци, поради което няколко сигнали могат да "сливане" в едно. Въпреки това, ако вашето приложение се изпълнява едновременно с много наследници, дори и като "пакет" за да се получи PID предпочитане обхождане през списъка за всяка поява на сигнала. Страничен ефект от използването на методи за обработка паралелизация е относително независимо от самата обработка между процеси, като всеки процес своя пространство изолиран памет и техните грешки. Всичко това означава, че дадена критична повреда в един от процесите, обикновено не води до рухването на цялата програма. В зависимост от вашите предпочитания и опит на процесите на изолиране на паметта може да бъде минус, защото благодарение на него в процесите първоначално няма споделени променливи или още няколко структури от данни, както и за обмен на информация между тях, ще трябва да упражнява допълнителни усилия, за да го организира с методите на IPC. Вие ще трябва да се обърне внимание и синхронизиране (за прекрачване на "писателите" Проблеми и "читатели"), данните в този обмен не се развали. А просто решение на този проблем е да се използват каналите (тръби), но те имат своите ограничения. Най-продуктивен със значителни обеми (стотици килобайта или повече) е като не-синхронен обмен на данни чрез споделена памет, но при условие, че данните се използва от място за съхранение, без допълнително копие на обща памет на друго място, а това ще изисква внимателна и точна дизайн и, Много е вероятно да се усложни от приложението.

многонишково

В момента тече GNU / Linux се различава от процесите в основната набор от качества и неща като функция призовава execve семейство (2), EXEC (3) в един от потоците. Т.е. и процеси и нишки планират обекти ядрото Scheduler може независимо да бъдат блокирани, за приемане на сигнали и т.н. В действителност, дори и на процеса на дете и потока се проявява по подобен начин с помощта на функцията за клонинг (2) списък на съответните флагове, които определят свойствата на генерирани обект (подробности можете да намерите в ръководството за тази функция).

Независимо от това, че все още е специфичните детайли по изпълнението, както и отношенията между процеси и нишки остава същото:

Отговор на входяща връзка поток продукт може, например, така че (също така е само илюстрация и не пълен код):

Новият конецът е създаден с помощта на pthread_create (3), който, ако е успешно, за поставяне на показалеца в паметта threadId породена от идентификатор на потока. Има един (тип нищожен *) сред аргументите pthread_create функция (3), за да предават нищо във функцията на стрийминг (което ще бъде началната точка на потока). Може да мине и една променлива (например, гнездо дръжка с новата връзка в този случай), първо изрично да се хвърли на отпада тип, а след това извърши обратно намаление вече в производствената функция. Ако трябва да мине някакъв блок (включително "шарени") данните, предавани указател към блока със същия двойно изрично тип.

Многонишковата програмиране е добро упражнение в параметър, тъй като обикновено се открива всички необходими външен поток от данни са комбинирани в една структура, която е пълна преди поток и указател към продукт, който след това се предава поток поток като функция аргумент. Благодарение на тази входна точка в потока често е само типа данни по тази тема (с изключение на минималния размер на това, което някои глобални данни) пряко или косвено (чрез указатели), което е полезно за по-голяма простота и ред.

В глобалния обхват обикновено се поставят на данни в същото време всички необходими потоци и която не се очаква да се промени, или на данни се обменят между нишки. Глобални предмети също могат да заявят мутекс и семафор, но това вероятно е до голяма степен определя от личните предпочитания - аз използвам в работата си, за да ги "говори" имена и обикновено са обявени в глобалния обхват.

Ние също трябва да спре в края на потока. В този контекст, потоците могат да бъдат два вида - Приложеното (приложен) и не е свързан (прекъснатото, офлайн и др Самостоятелна). Първите средства за потока приблизително същите като при този процес - след приключване на потока родител на детето трябва да "снасят" зад себе си с помощта pthread_join (3) функции, които трябва да се съхраняват и поток ID (threadId в примера). Ако не се интересувате функцията за обратен поток на стойност или че не извежда нищо, можете да създадете поток веднага изключен и след това няма да има нищо, което да поддържа системата и, съответно, да харчат средствата.

Важна точка в развитието на многонишковите приложения е нишка безопасно (безопасност резба), причинени в поток функция: безопасността и надеждността при изпълнение на функцията в контекста на множество потоци от същия процес. Това може да се осигури, например при използване на вече споменатите по-горе критичен участък, и / или други методи:

  • povtornovhodimost (повторно entrancy): В общия случай това е невъзможно да се предскаже как ще се планират работните процеси и планировчика на ядрото конец (в какъв ред, по кое време), и тя може да се случи, че една нишка ще бъде спряна по време на изпълнението на кода на някои функции и управление ще бъде назначен друга нишка, която ще се изпълнява същата функция, и след това се прехвърля обратно към спира потока. Povtornovhodimymi са функции по време на изпълнение, които не потоци забелязват това "заместване". От друга страна, nepovtornovhodimye функция може да се използва като "показатели за планиране на фактите" (макар и не на 100% от отговор). Povtornovhodimosti може да се постигне като се използват само локални променливи и с изключение на работа с глобални променливи, за да се променят.
  • местно съхранение: да се работи с всички необходими данни, вече е в контекста на потока, трябва първо да се направи копия от тях местни до променливите производствената функция за всяка нишка от само себе си.
  • атомност: има редица операции, при които се гарантира непрекъснатостта на ядрото, т.е., ако те са инициирани, те задължително да бъдат завършени в рамките на текущия поток без пауза; .. Обикновено това е елементарни операции като нарастване / намаляване.

комбинация Метод дебит

Дали обединението на двете по-горе методи, той обикновено избягва процеса на генериране на потоците - защо е необходимо копие от процеса с един куп правя каквото им скимне потоци? Вместо това, или всички необходими процеси се генерира предварително, за да създаде съединения и генерират потоци или генерирани "между пъти", както се изисква (т.е. отложено пълнене марж процес "пара", когато изтощени) от отделен, "примерно" и / или "чисти" процес. Подобен подход е оправдано в случаите, когато времето, прекарано в процеса на производство или конец за обработване на съединение е от съществено значение и трябва да се намали до минимум. Развитието на такива програми е доста трудна задача, най-вече заради необходимостта да разгледа внимателно и изграждане на междусистемни процес конци и взаимодействие. Може също така да изисква развитието на някои вътрешни команди и / или процеси за по-гъвкав и управляем взаимодействие между процеси и самите нишки.

заключение

Смесената подход може да се приложи, когато е необходимо да се съчетаят двете възможности, посочени в същото приложение.

В статията се засегна отмяната на потоци. В допълнение, тази част, както и други, все още включва значителна част от самостоятелна работа.

Изтегляне ресурси

Свързани теми

  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 1. Въведение в развитието на околната среда. Разбор опции за командния ред, подкрепа за вградени помощ, "демонизиране" на програмата.
  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 2. Пълен анализ на параметрите на командния ред.
  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 3. Работа с конфигурационния файл да се инициализира на вътрешните структури на програмата.
  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 4. Преглед на I / O техники, които се прилагат към мрежовите връзки.
  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 5: Методи за паралелна обработка на заявките мрежа (процеси, конци, и комбинации от тях).
  • Един пример за развитието на една проста многонишков уеб сървър с поддръжка на потребителски сесии в езика C. в операционната система GNU / Linux: Част 6: механизми за удостоверяване.
Подкрепете проекта - споделете линка, благодаря!