|
|
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Написал многопоточное приложение, на XP работает нормально, но на 2003 serv падает, причем странным образом, консолька просто исчезает без сообщений об ошиках и т.п.. Хотя падает очень редко все же очень неприятно. Так вот под подозрением у меня такие моементы: есть указатель, который может указывать на дин. выделенную память, либо NULL содержит. Проверку типа: Код: plaintext 1. не стал разделять критическими секциями для более быстрой роботы, т.е. в момент проверки теоретически p_root->pVal может быть изменено др. потоком с NULL на какой-то адрес свежевыделенной памяти. Мне интересно, может ли это привести к краху приложения?? Аналогично: Код: plaintext 1. не защищено от изменения др. потоком, тот же вопрос.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 18:37 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
т.е. по сути вопрос такой: Если я читаю значение переменной, и что др. поток может туда писать в любой момент времени, может ил это привести к плачевным результатам? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 18:44 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
насколько редко падает? скомпиль в дебуг лови вывод лови код возврата ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 19:22 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Tubrik пишет: Мне интересно, > может ли это привести к краху приложения?? Может, и аналогично во втором случае. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 19:33 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
maXmoнасколько редко падает? скомпиль в дебуг лови вывод лови код возврата 1. можно 50 раз подряд запускать и не упадет, а бывает неск. раз подряд (падает на загрузке, когда начинают обновляться данные в несколько потоков) 2. Чей код возврата, как/чем ловить? MasterZiv Tubrik пишет: Мне интересно, > может ли это привести к краху приложения?? Может, и аналогично во втором случае. Что может - понял, но почему, в смысле, каков примерный сценарий приводящий к падению? p_root->pVal, допустим, равен NULL, что может произойти "плохого", если в момент if ( p_root->pVal ) произойдет запись туда другого значения? Могу предположить только, что значение с NULL изменится, но "не полностью", в результате произойдет обращение к не той области памяти. Но тогда выходит, что запись значения в переменную не атомарна, т.е. происходит в неск. шагов, которые могу быть прерваны. Глупый сценарий, но другой пока не придумал) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 22:20 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
TubrikЧто может - понял, но почему, в смысле, каков примерный сценарий приводящий к падению?Указатель сам по себе мало пользы приносит. Ты работаешь на самом деле не с указателем, а с данными находящимися по адресу. Запись значения в указатель действительно атомарная операция и она не может быть прервана другим потоком, но выделение памяти и уж тем более заполнение этой памяти осмысленными данными - вот это уже совсем не атомарная операция. К тому же, если у тебя этот самый глобальный указатель может перенаправлятся или обнулятся, то поток должен быть уверен что другой поток не убьет данные по этому адресу пока он с ними работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2007, 23:38 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Tubrik пишет: > p_root->pVal, допустим, равен NULL, что может произойти "плохого", если > в момент if ( p_root->pVal ) произойдет запись туда другого значения? Обращение по адресу 0x00000000. В Win32 например младший мегабайт логической памяти приложения защищен от любого доступа, так что любое обращение туда приводит к Access Violaiton. > Но тогда выходит, что запись значения в переменную не атомарна, т.е. > происходит в неск. шагов, которые могу быть прерваны. Глупый сценарий, Да, запись в переменную не атомарна. Вообще в С++ пока нет понятия "атомарная операция", поэтому до выхода следующего стандарта можете забыть о таких техниках программирования. Используйте средства синхронизации, предоставляемые операционной системой. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 09:03 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
White OwlУказатель сам по себе мало пользы приносит. Ты работаешь на самом деле не с указателем, а с данными находящимися по адресу. Запись значения в указатель действительно атомарная операция и она не может быть прервана другим потоком, но выделение памяти и уж тем более заполнение этой памяти осмысленными данными - вот это уже совсем не атомарная операция. К тому же, если у тебя этот самый глобальный указатель может перенаправлятся или обнулятся, то поток должен быть уверен что другой поток не убьет данные по этому адресу пока он с ними работает. Если атомарная, то лучше сначала выделить память, заполнить осмысленнымид данными, а потом просто направить указатель на уже заполненную память. Перенаправляться и обнуляться он не может, может только "разунуляться" и изменяться некоторые члены структуры. Вообщем решил не гадать, а залочить все нафиг, ибо небольшой выйгрыш во времени потом может выйти боком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 12:11 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Теперь след. вопрос, касающийся этой же темы:) Через определенные интервалы времени запускается ф-ия, которая обновляет все данные программы. Время затрачиваемое на обновление может быть неограниченно большим. Поскольку эта ф-ия очень плотно работает с обновляемой структурой данных, то в принципе она должна захватывать эту структуру в понопольное использование до конца обновления. Но т.к. постоянно приходят запросы, и нужно обращаться к данным чтобы их обрабатывать, то полный захват типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. не приемлем. Мне интересно узнать, насколько разумно сделать так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. т.е. намеренно разлочивать данные, чтобы дать другим потокам к ним обратиться. Или услышать более интересный вариант.. И еще вопрос: обновляющий поток сделал THREAD_PRIORITY_BELOW_NORMAL, выходит на планочку меньше стандартного приоритета. Это чтобы он не мешался во время запросов. Есть ли в этом смысл? Т.е. не станет ли он медленнее покидать секцию: Код: plaintext 1. 2. 3. 4. Еще вопрос: выставление приоритета THREAD_PRIORITY_BELOW_NORMAL делает его приоритет ниже потоков его процесса или ниже всех потоков системы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 12:31 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Tubrik пишет: > не приемлем. Мне интересно узнать, насколько разумно сделать так: > void myClass::func_update() > { > while (get_data()) > { > LockData(); > // обновление порции данных > //... > UnlockData(); > Sleep(*0*); // вроде как должно переключать с этого потока > } > } > > > т.е. намеренно разлочивать данные, чтобы дать другим потокам к ним > обратиться. Или услышать более интересный вариант.. Это разумно, почему нет. Но только если перед UnlockData() данные находятся в валидном и консистентном состоянии. Иначе это делать некорректно. > И еще вопрос: обновляющий поток сделал THREAD_PRIORITY_BELOW_NORMAL, > выходит на планочку меньше стандартного приоритета. Это чтобы он не > мешался во время запросов. Есть ли в этом смысл? Т.е. не станет ли он > медленнее покидать секцию: Медленнее не станет покидать. Но если у тебя в системе есть более высокоприоритетные потоки (что наверняка), то есть риск, что обновляющий поток никогда не получит управление (или очень нескоро получит) и не освободит данные. > если да, то др. потоки будут его дольше ждать? > > Еще вопрос: выставление приоритета THREAD_PRIORITY_BELOW_NORMAL делает > его приоритет ниже потоков его процесса или ниже всех потоков системы? Всех потоков системы. Точнее так. Есть группы приоритетов. В каждой группе примерно 3-4 значения приоритета. Есть базовый приоритет процесса. Он равен среднему значению внутри группы. Приоритеты потоков определяются относительно базового приоритета процесса. Т.е. ты не можешь напр. поставить приоритет потока 1. Можешь только PROSESS_BASE-1. Ну а далее - в системе всегда есть высокоприоритетные процессы, так что всегда найдутся какие-то с более высоким приоритетом. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 14:06 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
MasterZiv Медленнее не станет покидать. Но если у тебя в системе есть более высокоприоритетные потоки (что наверняка), то есть риск, что обновляющий поток никогда не получит управление (или очень нескоро получит) и не освободит данные. Ага, именно это меня и интересовало, т.е. если в системе есть более приоритетные процессы (а они конечно же есть, хотябы потому, что обновляющий поток с приоритетом ниже нормального), то обновляющий поток будет дольше обрабатывать разделяемый реруср, а значит запросы буду дольше ждать. Выходит то, ради чего его приоритет занижался (ради уступания времени запросам), выполняться не будет? Получается нужно сделать всем одинаковый приоритет и не стараться манипулировать приоритетами (хотябы в случае, когда потоки разделяют один реусрс)?? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 14:21 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Насколько я помню, в WIN32 присвоения указателей типа PVOID и переменных типа (LONG, ULONG, INTPTR, UINTPTR) атомарны, соответственно атомарны и присвоения указателей эквивалентного размера. Так, что скорее всего проблемы не в присвоении, а в алгоритме. По поведению - типичный race conditions. Обычный способ отладки - изучение алгоритма или, если ничего не приходит в голову, расстановка вызовов Sleep(0) (особенно полезно их вызвать перед и после функций ожидания). Tubrik MasterZiv Медленнее не станет покидать. Но если у тебя в системе есть более высокоприоритетные потоки (что наверняка), то есть риск, что обновляющий поток никогда не получит управление (или очень нескоро получит) и не освободит данные. Ага, именно это меня и интересовало, т.е. если в системе есть более приоритетные процессы (а они конечно же есть, хотябы потому, что обновляющий поток с приоритетом ниже нормального), то обновляющий поток будет дольше обрабатывать разделяемый реруср, а значит запросы буду дольше ждать. Выходит то, ради чего его приоритет занижался (ради уступания времени запросам), выполняться не будет? Обновляющий поток никогда не получит управления, только если потоки с более высоким приоритетом всегда планируются на исполнение. При правильно написанных программах такое может произойти только если не хватает вычислительной мощности процессора. Как правило, в этом случае заменяется компьютер, потому, что работать на нем все равно невозможно. В случаях, когда высокоприоритетный поток ожидает освобождения ресурса занятого низкоприоритетным рабочим потоком система должна поднимать приоритет рабочего потока. В Win32 это точно делается (msdn): Priority Inversion Priority inversion occurs when two or more threads with different priorities are in contention to be scheduled. Consider a simple case with three threads: thread 1, thread 2, and thread 3. Thread 1 is high priority and becomes ready to be scheduled. Thread 2, a low-priority thread, is executing code in a critical section. Thread 1, the high-priority thread, begins waiting for a shared resource from thread 2. Thread 3 has medium priority. Thread 3 receives all the processor time, because the high-priority thread (thread 1) is waiting for shared resources from the low-priority thread (thread 2). Thread 2 won't leave the critical section, because does not have the highest priority and won't be scheduled. The scheduler solves this problem by randomly boosting the priority of the ready threads (in this case, the low priority lock-holders). The low priority threads run long enough to exit the critical section, and the high-priority thread can enter the critical section. If the low-priority thread doesn't get enough CPU time to exit the critical section the first time, it will get another chance during the next round of scheduling. Windows Me/98/95: If a high-priority thread is dependent on a low-priority thread that will not be allowed to run because a medium priority thread is getting all of the CPU time, the system recognizes that the high-priority thread is dependent on the low-priority thread. It will boost the low-priority thread's priority up to the priority of the high-priority thread. This will allow the thread that formerly had the lowest priority to run and release the high-priority thread that was waiting for it. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 17:15 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
teras пишет: > Насколько я помню, в WIN32 присвоения указателей типа PVOID и переменных > типа (LONG, ULONG, INTPTR, UINTPTR) атомарны, соответственно атомарны и > присвоения указателей эквивалентного размера. Откуда такие сведения ? Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 17:29 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
teras То, что система будет поднимать временами его приоритет, дабы не дать бедняге совсем заглохнуть, это понятно. Но вопрос в том, стоит ли ему (потоку обновления) понижать приоритет для того, чтобы он "уступал" время запросам, и не даст ли это побочный эффект в том, что он на более низком приоритете будет дольше "возиться" внутри критической секции, которую, собственно, и ожидают потоки обрабатывающие внешние запросы.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 17:29 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
MasterZiv teras пишет: > Насколько я помню, в WIN32 присвоения указателей типа PVOID и переменных > типа (LONG, ULONG, INTPTR, UINTPTR) атомарны, соответственно атомарны и > присвоения указателей эквивалентного размера. Откуда такие сведения ? Posted via ActualForum NNTP Server 1.4 Традиционно - MSDN. Interlocked Variable Access The interlocked functions provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory. Simple reads and writes to properly-aligned 32-bit variables are atomic. In other words, when one thread is updating a 32-bit variable, you will not end up with only one portion of the variable updated; all 32 bits are updated in an atomic fashion. However, access is not guaranteed to be synchronized. If two threads are reading and writing from the same variable, you cannot determine if one thread will perform its read operation before the other performs its write operation. Simple reads and writes to properly aligned 64-bit variables are atomic on 64-bit Windows. Reads and writes to 64-bit values are not guaranteed to be atomic on 32-bit Windows. Reads and writes to variables of other sizes are not guaranteed to be atomic on any platform. То есть, операции чтения и записи 32-битных, выровненных значений - атомарны. Выравнивание по умолчанию у VC - или 4 или 8 байт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 17:41 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Tubrik teras То, что система будет поднимать временами его приоритет, дабы не дать бедняге совсем заглохнуть, это понятно. Но вопрос в том, стоит ли ему (потоку обновления) понижать приоритет для того, чтобы он "уступал" время запросам, и не даст ли это побочный эффект в том, что он на более низком приоритете будет дольше "возиться" внутри критической секции, которую, собственно, и ожидают потоки обрабатывающие внешние запросы.. Как следует из приведенного фрагмента, если есть ожидающие потоки с высоким приоритетом - у обрабатывающего потока поднимется приоритет, а значит дольше ждать им не придется (собственно это и называется инверсией приоритета). Нужно ли поднимать/опускать приоритеты - на такой вопрос ответить не так просто - все зависит от конкретной задачи, распределения нагрузок, различных ограничений. Как правило необходимости в этом нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 17:54 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
TubrikТеперь след. вопрос, касающийся этой же темы:) Через определенные интервалы времени запускается ф-ия, которая обновляет все данные программы. Время затрачиваемое на обновление может быть неограниченно большим. Поскольку эта ф-ия очень плотно работает с обновляемой структурой данных, то в принципе она должна захватывать эту структуру в понопольное использование до конца обновления. Но т.к. постоянно приходят запросы, и нужно обращаться к данным чтобы их обрабатывать, то полный захват типа: ....................................... Тут мне бы хотелось спросить, все ли потоки, обращающиеся к данной структуре изменяют данные. У меня есть подозрение что некоторые из потоков только читают данные, в этом случае может быть намного эффективнее использовать блокировки на чтение/запись ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 18:02 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
terasНасколько я помню, в WIN32 присвоения указателей типа PVOID и переменных типа (LONG, ULONG, INTPTR, UINTPTR) атомарны, соответственно атомарны и присвоения указателей эквивалентного размера.Это не совем верно, Win32 здесь не при чем. На самом деле, атомарны операции записи регистра процессора в память. До тех пор пока элементарный тип языка не превышает размер регистра процессора, работа с этим элементарным типом будет атомарной. Все перечисленные собственные типы платформы Win32 в действительности являются одним и тем же 32-х битным типом. И действительно работа с ними будет атомарной на процессорах с 32+ битными регистрами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 18:19 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
Sandro_K Тут мне бы хотелось спросить, все ли потоки, обращающиеся к данной структуре изменяют данные. У меня есть подозрение что некоторые из потоков только читают данные, в этом случае может быть намного эффективнее использовать блокировки на чтение/запись Обновляющий поток(и) перезаписывают данные если они изменились со времени последнего обновления. Потоки обрабатывающие запросы только читают данные, если они есть, если их нет, тогда делают запрос на сервер и фактически создают новые данные в кэше. (Само приложение - типа кэш данных, хранит только те, к которым были обращения.) Соответственно обнуляться данные не могут, они могут либо создаваться, либо изменяться. Что такое блокировки на чтение/запись? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 18:49 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
White Owl terasНасколько я помню, в WIN32 присвоения указателей типа PVOID и переменных типа (LONG, ULONG, INTPTR, UINTPTR) атомарны, соответственно атомарны и присвоения указателей эквивалентного размера.Это не совем верно, Win32 здесь не при чем. На самом деле, атомарны операции записи регистра процессора в память. Конечно, вы правы, атомарность реализуется на аппаратном уровне. Но это несколько другое. Наличие таких ограничений в спецификации обозначает то, что Win32 никогда не будет портирован под платформы, где присвоение LONG будет не атомарным, а значит этим можно пользоваться, вне зависимости от типа процессора. TubrikЧто такое блокировки на чтение/запись? Повышение гранулянтности блокировок по уровню доступа. Читатели и писатели взаимоисключающи. При этом в критическую секцию, одновременно может войти несколько читателей. Писатель может быть либо один, либо несколько, в зависимости от реализации. Хороший пример реализации можно найти в pthreads/win32. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2007, 19:20 |
|
||
|
разделение ресурсов
|
|||
|---|---|---|---|
|
#18+
teras Повышение гранулянтности блокировок по уровню доступа. Читатели и писатели взаимоисключающи. При этом в критическую секцию, одновременно может войти несколько читателей. Писатель может быть либо один, либо несколько, в зависимости от реализации. хорошая идея, спасибо) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2007, 12:52 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=34776055&tid=2028231]: |
0ms |
get settings: |
8ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
213ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
81ms |
get tp. blocked users: |
2ms |
| others: | 233ms |
| total: | 580ms |

| 0 / 0 |
