Re[12]: SuspendThread - зло???
От: Аноним  
Дата: 12.10.06 12:28
Оценка:
Здравствуйте, apple-antonovka, Вы писали:

AA>Скомпилируйте пример ниже чтоб все что я писал выше не было голословным. И учтите что константы подобраны для максимально быстрого и показательного проявления эффекта. Увеличтье слипы, поменяйте расположение маллоков и вы запросто можете добится того что код будет работать час, сутки и больше, но потом зависнет.


AA>
AA>#include <stdlib.h>
AA>#include <process.h>
AA>#include <windows.h>

AA>void __cdecl thread(void *p)
AA>{
AA>for(;)
AA>{
AA>void *p=malloc(0x100000);
AA>Sleep(1);
AA>free(p);
AA>}
AA>}

AA>int main(int argc, char* argv[])
AA>{
AA>HANDLE h = (HANDLE)_beginthread(thread,0,NULL);

AA>for(;;)
AA>{
AA>printf("[%08x] I'm still alive!\n",::GetTickCount());
AA>SuspendThread(h);
AA>void *p=malloc(0x100000);
AA>free(p);
AA>ResumeThread(h);
AA>Sleep(1);
AA>}

AA>return 0;
AA>}
AA>


В этом примере, если используется многопоточная CRT (а однопоточную тут и вовсе использовать некорректно), ф-я malloc(), вызываемая из ф-ции thread() наступает на критическую секцию, после чего основной поток останавливает поток thread(), и вызвавает все тот же malloc(). естественно возникает дедлок. Ровно таже фигня и со всеми остальными примерами.

А вот это:
AA>Спор перетекает в бесполезный флейм. Извините, но по должности я архитект и если увижу что какой то из программеров в моем проекте пишет одну из перечисленных в начале функий, я его настоятельно попрошу обойтись без нее.
ничто иное, как понтокидательство, к делу относящееся весьма косвенно.
Re[13]: SuspendThread - зло???
От: Аноним  
Дата: 12.10.06 14:06
Оценка:
http://www.rsdn.ru/Forum/Message.aspx?mid=2100705&amp;only=1
Автор: apple-antonovka
Дата: 08.09.06
Re[8]: SuspendThread, ResumeThread для pthread
От: remark Россия http://www.1024cores.net/
Дата: 13.10.06 04:09
Оценка:
Здравствуйте, apple-antonovka, Вы писали:

А>>Упс... А можно ли поподробнее чем череват SuspendThread в системных библиотеках (каких???). Я что-то в этой жизни похоже пропустил. здесь я даже упоминания про SuspendThread не увидел (зрение — плохое, английский ещё хуже, а поиск ничего не дал ).

AA>Вообще говоря в любых. Многие API функции используют синхронизацию для thread-safe работы со своими внутренними структурами. memory manager тоже естественно использует дабы можно было одновременно из нескольких потоков выделять/освобождать память банальнымм malloc/free/new/delete. Если поток будет заморожен в тот момент когда он находится в синхронизироанном коде, любой другой поток при доступе к синхронизированными данным зависнет. Т.е.:
AA>Поток A вызывает malloc. malloc уходит в HeapAlloc во втором параметре которого нету флага HEAP_NO_SERIALIZE. HeapAlloc вызовет RtlAllocateHeap. RtlAllocateHeap завладеет какимто мутексом в недрах ntdll дабы сериализовать работу с кучей между потоками. И в тот момент как поток А будет ковыряться в куче выделяя память, поток Б ему сделает SuspendThread. Поток А останется замороженным на середине выделения памяти. Все. Любая попытка другого потока выделить/освободить память приведет к его ожиданию пока поток А освободит мутекс. А он его не освободит потому что он suspended. Прога повисла. Если бы вместо SuspendThread юзался бы TerminateThread то поток А был бы убит во время работы с кучей, мутекс бы освободился, но куча бы осталась в поврежденном состоянии и прога бы свалилась.
AA>Пример с памятью — это просто самый показательный, на самом деле многие апи функции чегото лочат. Иначе они не были бы thread-safe.

Всё это верно только для "старых" lock-based OC.

Вот это "Иначе они не были бы thread-safe" вообще имхо устаревшее мнение, не факт, что верно для всех функций даже для современных ОС, в т.ч. для Win. Т.к. они тоже потихоньку допирают до lock-free. Достаточно поглядеть на функцию InitializeSListHead. И thread-safe и без критических секций.

lock-free подход лишён многих недостатков традиционного lock-based и в т.ч. всего описанного выше, а также deallock'ов, priority inversion, control serialization, zero scalability и т.д.

Правда на данном этапе, что касается полностью lock-free ОС, это пока "университетские" разработки. Т.ч. сейчас SuspendThread() делать не надо


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[14]: SuspendThread - зло???
От: Аноним  
Дата: 13.10.06 09:07
Оценка:
А>http://www.rsdn.ru/Forum/Message.aspx?mid=2100705&amp;only=1
Автор: apple-antonovka
Дата: 08.09.06


я про это и говорю. понятно, что не сама malloc встает на лочку, а виндовая функция.
Re[15]: SuspendThread - зло???
От: Аноним  
Дата: 13.10.06 09:10
Оценка:
А>я про это и говорю. понятно, что не сама malloc встает на лочку, а виндовая функция.
Это зависит от реализации. Нельзя закладываться на реализацию. Поставьте STLPORT с SGI optimized allocator получите дедлок на уровне STL. Мыслите шире. SuspendThread управлет объектом (потоком) на том уровне на котором вы не имеете полного контроля над этим объектом из userspace.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.