Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки WinApi и GCC, Обуздание потоков 
:(
    Опции темы
Dem_max
Дата 16.7.2012, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Ну в сабже есть такой как раз момент.
Если эта функция будет в потоке, который породил еще один поток.
Код

bool Z::Basis::Thread::Wait() {
    unsigned long WaitResult = WaitForSingleObject(_ThreadHandle, INFINITE); // ..............................................................> Ожидание завершения потока
    if (WaitResult == WAIT_OBJECT_0) // .



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
NYX
Дата 16.7.2012, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



В реальности врядли будет вообще использоваться эта функция smile Я написал ее просто что бы main преждевременно не вылетала smile Да и с небольшим мэйном если приложение виснет, в Olly просто условие немного меняю и прога развисает smile В Wait можно аргументы поставить что бы не было вечного ожидания. А ваще принципиально от INFINITE ничем не застр###шься. Так что, не знаю, как-то не хочется выдумывать всякого рода хаки. Я думаю что чем примитивныее объект-поток, тем более он будет гибок. Вот только с синхронизацией подразбирусь и с атомарностью. Кстати, а кто нибудь может рассказать про критические секции? А то у щупака просто выложено как ФАКТ что такое есть + описание объектов. Но в связке с потоками примера не описано. Мьютексы и семафоры это ясно, они в теле потока уже там туда-сюда-используются... а вот с критическими секциями ничо не понял. А, ну на WinAPI если кто то использовал. Хотя если принцип такой есть в какой то библиотеке, то можно и на примере библиотеки.

Это сообщение отредактировал(а) NYX - 16.7.2012, 13:24
--------------------
'long long long' is too long for GC
PM   Вверх
NYX
Дата 16.7.2012, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Расковырял инфы про критические секции. Собстно вот статья http://www.rsdn.ru/article/baseserv/critsec.xml
Стало быть:
* Критическая секция это объект, размещение которого определяется функциями EnterCriticalSection и LeaveCriticalSection в параметрах которых
принимается указатель на объект секции. Далее, перед оперированием какого либо данного, делается ентер, по завершению оперирования
лив. Соответственно можно использовать вложенные ентеры и ливы, если например поток может обращаться ЛИБО - ЛИБО соответственно.
так же выходит, область критической секции не начнет свое выполнение и не прервется по середине. Весч прикольная. Но почему тогда
такие лакомые плюшки мало где используются? Напр. сервера, где почти во всех как в одном юзаются мьютексы или симафоры. В сильно взрослых
серверах типо апача (мельком просмотрел) тоже вроди бы мьютексы, в микросервере null httpd...
А что стоило бы, например, внутренние данные объекта потока защитить критсекциями... плюс, дать возможность объекту-потоку принимать
объект критсекции, или более того... если имеется подвызов, то просто обуславливать его вызовами ентер и лив. Тогда ВСЕ используемое в потоках-
потомках коллектора будет (типо)атомарным. А в случае если например используется связка коллекторов... то можно использовать нечто вроди
массива (стека?) объектов критических секций. Довести до автоматизма опрос списка секций в выполнении определенных задач (ну типо не все
элементы объекта, а зависимые от выполнимой задачи). Ух! Сколько всего придется погрызть и попробовать на зуб.
--------------------
'long long long' is too long for GC
PM   Вверх
Dem_max
Дата 16.7.2012, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

(типо)атомарным

Типо атомарным не будет никак, атомарнось подразумевает выполнение чего либо за один такт процессора.

Цитата

Но почему тогда
такие лакомые плюшки мало где используются?

Используются

Цитата

В операционных системах семейства Microsoft Windows разница между мьютексом и критической секцией в том, что мьютекс является объектом ядра и может быть использован несколькими процессами одновременно, критическая секция же принадлежит процессу и служит для синхронизации только его потоков.

Критические секции Windows имеют оптимизацию, заключающуюся в использовании атомарно изменяемой переменной наряду с объектом «событие синхронизации» ядра. Захват критической секции означает атомарное увеличение переменной на 1. Переход к ожиданию на событии ядра осуществляется только в случае, если значение переменной до захвата было уже больше 1, то есть происходит реальное «соревнование» двух или более потоков за ресурс.

Таким образом, при отсутствии соревнования захват/освобождение критической секции обходятся без обращений к ядру.



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
NYX
Дата 16.7.2012, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Ну да но я и написал ТИПО smile само собой никакой атомарности нет smile А где например используются? Глянуть бы исходники... На сайте IBM (не вспомню уже где я это и как нашел) статья была про легкие сервера (ПО разумеется)... там были ссылки я частично поразглядывал исходники, но там по большей части на разных языках где ... нет того что в С++ пожжерживается. Единственное более менее подходящее null httpd было и счас на харде лежит, он под МС но принцип примерно такой же как и при WinAPI CreateThread (почти). В общем смысил один за исключением _beginthread. но там нет крит. секций. Апач даже ковырять толком не стал smile жутко стало при одном виде smile недели две-три придется на листке всю модель выписывать + еще хз сколько времени на то что бы отсечь лишнее и внять логику. Да и к тому же там тоже вроди бы нет критических секций. Ну хотя с секциями я относительно более менее разобрался для себя, хотя пример лучше бы узреть. Пойду гуглить smile
--------------------
'long long long' is too long for GC
PM   Вверх
bsa
Дата 17.7.2012, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Dem_max @  16.7.2012,  19:24 Найти цитируемый пост)
Типо атомарным не будет никак, атомарнось подразумевает выполнение чего либо за один такт процессора.
Да ладно?  smile А если процессор в принципе не имеет ни одной инструкции, которая выполнялась бы быстрее n>1 тактов? Более того, современные процессоры (x86) выполняют инструкции не за один такт. Просто, пока одна инструкция выполняется, следующая дешифруется, а третья извлекается из памяти (это упрощенно).
Может все-таки стоит почитать определение атомарности?
PM   Вверх
NYX
Дата 17.7.2012, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Типо конвеерность все такое smile Всеж атомарность получается может поддерживаться железом, но это не зависит от кол-ва действий. Атомарным является данное которое в данный момент времени доступно одному потоку и нерушимо остальными потоками. Тогда получается мое утверждение об атомарности - не типо атомарное, а полноценно атомарное (об критических секциях).

Это сообщение отредактировал(а) NYX - 17.7.2012, 15:32
--------------------
'long long long' is too long for GC
PM   Вверх
NYX
Дата 19.7.2012, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Все! Я Запутался.
--------------------
'long long long' is too long for GC
PM   Вверх
bsa
Дата 19.7.2012, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(NYX @  19.7.2012,  15:07 Найти цитируемый пост)
Все! Я Запутался. 

в чем? в атомарности?
PM   Вверх
NYX
Дата 19.7.2012, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Да в ней акаянной! Вот, критические секциии ваще вынесли мне мозг. Ступор произошел еще в самом начале, когда была попытка как то изолировать данные класса-потока от множественных обращений к ним из:
1) внутренней реализации потока
2) внешних вызовов других потоков в т.ч. главного потока процесса

Путаница началась с вложенностью критических секций, а так же возможность дедлока в случае витиеватых возможностей класса. В какой то момент он может получиться, в какой то - нет. ООООЙ БОЖЕ!!! Это какой то АД! Вот логически потоки понять реально. А вот как сделать наиболее примитивную - простую автомарность. Пусть даже код будет избыточным, но его понимание было бы простым. Я уже подумываю сделать реализацию потоков и атомарности с помощью низкого уровня. Мне кажется что такая реализация даже будет лушче. Например, привязка данного к потоку. В случае если от коллектора ответвлено более одного потока, коллектор не опзволит обратиться к подключенным к нему данным. Это всего то лишь надо сделать подобие встроенных типов данных, а точнее дополнить POD парочкой флагов и полей под идентификатор коллектора. В общем решить на низком уровне будет от части и сложнее и проще... но блин опять же гемор, это все будет делаться ВНЕ реализации какого либо проекта и если надо будет подызменить реализацию, надо будет пересобирать например ту же DLL работающую с потоками и переподключать.... в общем пипец.
Может есть какая то стандартная схема гарантирующая атомарность данных? что бы можно было бы буквально просто указывать, -> вот тебе внешние данные товарищь поток, читай там оверхед (или какой нибудь объект рядом с ними) и смотри, не балуй с чтением\записью.

Да, кстати, в критических секциях я запутался в силу того, что не понял как они работают в низах. Вот допустим, выделил я внутри реализации потока блок кода и работы с данными. Окей. Второй, дублирующий этот код в своем потоке - поток, не может обратиться до тех пор пока ЭТА СЕКЦИЯ кем -то занята. Окей. с этим все ясно. А если допустим, я хочу изолировать вызовы printf для двух потоков в двух областях кода? Это надо писать и там и там EnterCriticalSection. Окей, а если рядом с вызовом printf используется инициализация какого то обхекта, и делается в одном из двух экземпляре. Но опять же может использоваться другими двумя потоками. Надо делать опять очередную критсекцию? Обобщаться все эти блоки, для выявления общих секций, которые не нарушили бы данные... блин это просто АД!  smile 

Это сообщение отредактировал(а) NYX - 19.7.2012, 16:57
--------------------
'long long long' is too long for GC
PM   Вверх
NYX
Дата 19.7.2012, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



 smile  я даже представить не могу как ваще проводить тестирование многопоточных приложений ухахаха
мои мозги в кофемолке  smile 
--------------------
'long long long' is too long for GC
PM   Вверх
bsa
Дата 19.7.2012, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(NYX @  19.7.2012,  20:52 Найти цитируемый пост)
 я даже представить не могу как ваще проводить тестирование многопоточных приложений ухахаха

думаю, это вообще мало кто представляет. smile 
Цитата(NYX @  19.7.2012,  17:53 Найти цитируемый пост)
Да, кстати, в критических секциях я запутался в силу того, что не понял как они работают в низах.

просто Microsoft назвала критической секцией то, что обычно называют захватом мьютекса. Так как они мьютекс сделали ядерным. Так вот, забудь про ядерный мьютекс. Речь идет о межпоточных мьютексах (фьютексах). Реализуются они через простейший атомарные операции процессора. При захвате мьютекса происходит изменение целочисленной переменной. При одном значении мьютекс считается успешно захваченным, при других значениях он считается захваченным другим процессом, в итоге текущий поток передает управление ядру. При возврате управления происходит еще одна попытка захвата... Если интересуют детали, то см. http://locklessinc.com/articles/mutex_cv_futex/
PM   Вверх
NYX
Дата 20.7.2012, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Стало быть сложность критических секций заключается в том, что нет ЯВНОСТИ указания "кто ваще кого чо?". Фьютекс является "Сходным образом оптимизированы объекты CRITICAL_SECTION в Win32 API, а также FAST_MUTEX в ядре Windows" по словам википедии. Сейчас более менее начал вникать в назначение мутексов и семафоров, благодаря какому то документу из НГУ на тему "Аспекты параллелизма", который описывает аспекты и реализации для Win\Linux после основополагающей теории. Буквально спас меня этот документ. Он был послан богами свыше, однозначно  smile ! Значит, получается что... критические секции, это своего рода IF с возможностью try на случай если помимо блока IF имеются какие либо еще задачи. В случае с мьютексами и симафорами это уже принудительное самоисключение потока из очереди (вне реализации, скажем так по теории). Получается что... для точного определения, что надо использовать, мьютексы, семафоры или некий гибрид "критическую секцию", необходимо точно знать какая задача у этих потоков и уже применять ТОТ или ИНОЙ способ, возможно зонально, а возможно на уровне ассортимента или наследственности объектов (для С++). 

Я решил поставить для себя такую задачу, которая не относится к реальным требованиям или реальным мирским потребностям. Выучить потоки на примере сервера, где модель сервера примерно такая:
1) поток который обрабатывает входящие данные и формироует очередь сообщений (подразумевается логика писатель-читатель)
2) множество потоков которым отведена ЧАСТЬ очереди (группировка и разнообразие потоков может диктоваться например скоростью соединения)
3) поток который производит рассылку обработанных данных по клиентам.

Как можно реализовать такую модель? Какие средства обеспечения атомарности данных необходимы для реализации. Попробую налету сформировать
подзадачи.
1) Поток принимающий данные от пользователя, позволяет засыпать\просыпаться потоку 2го пункта. Это важно! На случай если клиентов очень много но все они в разных категориях. Так, получится что для медленных клиентов с нечастыми запросами поток будет засыпать чуть чаще, но приоритет таких потоков (на уровне выполнения ОС) будет немного выше других.
2) потоки обрабатывающие данные, должны учитывать определенные условия. Например, поступившие данные от U1 на загрузку файла. Но, в процессе загрузки файла, U2 изменил пару байт. Варианта два - 1) прекратить закачку, дождаться обновления и самовозобновить закачку ( эгоизм среди потоков! О да, рекомендуемо). 2) Дождаться закачки - обновить данные (не рекомендуемо в силу больших потреблений ресурсов ЦП и трафика, так как более новое данное один шишъ придется закачивать по новой, но юзверь может и не знать о том, что данное было обновлено!!!!! ЭТО ВАЖНО!).
3) Потоки рассылки, являются чем то вроди дублирующего усилителя (аля РЭА). Где например, находящиеся в ОДНОМ ЗАЛЕ ОБМЕНА ФАЙЛАМИ учитываются такие условия описанные в пункте 2. То есть, грубо говоря, сервер и потоки могут быть уверены, что U1 не нарушит данные обрабатываемые в другом ЗАЛЕ для U234-517. Сами по себе потоки, могут пробуждаться в случае если очередь не пустая. Опять же, потоки могут обрабатывать отдельные части очередей. ХОТЯ! Все эти области очередей можно представить в виде множества стеков smile Как для потоков 1го пункта так и для 3го пункта. Очереди в таком смысле будет своего рода связанными... то есть, если есть очереди для 1го потока в виде QS[1...3] то и для 3го пункта потоков так же QS[1...3]. Наиболее важное! U[?] пользователи могут перестраиваться в произвольный момент времени из одной QS в другую!
ДАДАДА! Что я еще заметил! У пользователя можно установить мин-макс ( 0 < ?) пунктов очереди, и уже ранее сконфигурированный сервер при авторизации пользователя, создал бы болванку пустой очереди! Хотя в представлении очереди как СТЕКА это очень сложно... представить... маллок и реаллок и прочее что ли? В общем это второстепенно уже наверно.
Это образно. Но я думаю что выполнив такую задачу, потоки будут для меня семечками. Хочется додуматься самому, но сейчас понимаю, что на это надо время, поэтому взываю о помощи опытных людей smile

Как вы думаете? Вот навскидку, без кода и примеров, сугубо на пальцах, как такое реализовать используя мьютексы-семафоры-критсекции? Что будет избыточным? Что будет необходимым? smile

стало быть имеется получается вот что:
U1 -\_ QS1 ~ TI -> TC -> TO (thread in -> thread calc -> thread out)
U2 -/

U3 - QS2 ~ TI -> TC -> TO

U4 -\
U5 - |_ QS3 ~ TI -> TC -> TO
U6 -/

То есть в своем начале, каждый юзер имеет 3 потока Вход -> обработка -> выход, и в случае (ухахаха ИНТИМНОЙ) близости юзверей, их потоки сливаются в едином экстазе обрабатывая ВСЕ их запросы по некой событийности.

Значит, общими данными могут явиться данные, у которых более 1го владельца. Вроди бы логично получается. Чего стоит указать потоку с каким мьютексом из множества он имеет дело.. допустим так.

Далее, отделиться от очереди и перейти в свою... может означать копирование не обработанных данных СТАРОЙ ОЧЕРЕДИ, ровно таким же образом как и слияние очередей... но можно сделать очередь для множества, как массив очередей, где i оперируемая поток очередь на данный момент времени. Очередь является атомарным данным (ну или для корректности, множеством атомарных данных. Хотя первое наверно точнее, так как элементы в целом и есть неделимое для потоков данное). Окей, с этим более менее разобрались. Но как внутри этой всей схемы, идентифицировать юзверей например по категории скорости соединения? Так как ->
* Пользователи со скоростью соединения ОТ и ДО принадлежат одной группе, а те что от ДО и ДО-ДО ко второй....
* Те кто в группе с низким пропускным каналом обрабатываются приоритетнее чем те у кого канал быстрее. Если в очереди стоят 3-4 потока на группу быстрых клиентов и появляется медленный, то после НЫНЕШНЕГО клиента сразу идет медленный, после чего обслуживаются те 3-4 быстрых, если более нет медленных. ДА! Только так. Сервер можно будет допустим конфигурировать низший порог скорости + кол-во низших скоростных клиентов, дабы не приводить к обработке ТОЛЬКО низших клиентов. Это уже иная задача и в целом это дело можно контролировать например вручную, админам! Иначе, для чего они тогда нужны админы, как если не для этого smile

ДАЛЕЕ!
Уже вроди бы более менее мне ясно что да как.... но вот вопрос smile Что если например будет необходимо разбить 3 типа потоков на 2 процесса, где 1 процесс выполняет функцию некого воркера, работающий только с формированием очереди и с I\O, а второй процесс отвечает за вычисления и отправку запросов на БД например, в которой хранятся файлы. Опять же, мутексы, фьютексы, семафоры, критсекции... кошмар. УЖАС!

Это сообщение отредактировал(а) NYX - 20.7.2012, 01:25
--------------------
'long long long' is too long for GC
PM   Вверх
Dem_max
Дата 20.7.2012, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39





--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
NYX
Дата 20.7.2012, 05:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

Репутация: нет
Всего: нет



Спасибо! Читаю. Вот только что нарвался на эту серию статей еще http://www.sofmos.com/lyosha/Articles/multithreading1.html
Затарился пищей для ума. Читаю smile
--------------------
'long long long' is too long for GC
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0920 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.