Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > Критические секции (CRITICAL_SECTION) |
Автор: neokoder 11.3.2011, 10:17 | ||||
Привет коллеги. Вот у Рихтера прочитал, что иногда InitializeCriticalSection и EnterCriticalSection могут вызывать исключения, очень редко, но всё же могут. Поэтому решил написать 2 универсальные функции инициализации и входа в критическую секцию. Если у меня есть какие-то "жучки" в коде был бы рад если вы мне на них указали, особенно это касается использования goto, не возникнет ли каких-либо проблем после такого использования.
А использовать примерно так:
|
Автор: Estranged 12.3.2011, 13:32 |
Внимательно читайте документацию. Английским по белому написано про эти исключения: http://msdn.microsoft.com/en-us/library/ms682608%28v=vs.85%29.aspx. This function can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout. Do not handle a possible deadlock exception; instead, debug the application. Windows 2000: In low memory situations, EnterCriticalSection can raise an exception. Do not attempt to handle this exception; instead, either terminate the process or allow the exception to pass to the unhandled exception filter. To avoid an exception due to low memory, call the InitializeCriticalSectionAndSpinCount function to preallocate the event used by EnterCriticalSection instead of calling the InitializeCriticalSection function, which forces EnterCriticalSection to allocate the event. Preallocating the event is not necessary on Windows XP or later because EnterCriticalSection is guaranteed not to fail due to lack of resources. Старина Рихтер хорош, несомненно, но иногда данные там не соответствуют нынешним реалиям. А второе, теперь разве плюсовые catch ловят SEH исключения от windows? VS 6 точно ловила, а вот 2008 уже нет ![]() |
Автор: Estranged 12.3.2011, 14:31 |
Про ключи компилятора я как-то и не подумал. А что будет, если все 10 попыток TryEnterCriticalSection неудачны? Это типа как ошибка (printf("Error: can't enter critical section");) или все же просто кто-то слишком надолго занял секцию, надо всего лишь чуть-чуть подождать? |
Автор: neokoder 13.3.2011, 21:33 | ||||
В общем сошлись на другом форуме, что лучше всё же использовать классический вариант. Проверил работу пары потоков. Если первый поток зависает с завладением критической секции, а второй входит в цикл ожидания освобождения этой крит. секции. Всё -труба! Даже если сделать TerminateThread, а потом DeleteCriticalSection и InitializeCriticalSection всё равно второй поток остаётся висеть. Уже видимо в ожидании непонятно чего. Хотя я считаю Microsoft могли бы предусмотреть для критических секций такую же штуку как и для мьютекса, т.е. если поток завершается через TerminateThread, то критическая секция должна быть освобождена. Или вообще добавить спец. функцию, позволяющую принудительно освободить критическую секцию. Тогда остаётся действительно только одно - заключать в критическую секцию только код, который гарантированно не зависнет. А я хотел было написать что-то универсальное, для любого случая... В общем тогда классика - наилучший вариантом будет:
И InitializeCriticalSectionAndSpinCount вызывать так:
В итоге получим снижение производительности только для Windows 2000, зато упростим себе задачу программирования крит. секций. Добавлено через 42 секунды Решено. |