powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / WIN: EnterCriticalSection/LeaveCriticalSection
10 сообщений из 10, страница 1 из 1
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209471
зеленый админ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Являются ли процедуры из сабжа ref counted?
По идее из доки микрософта

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682608(v=vs.85).aspx

msdnA thread must call LeaveCriticalSection once for each time that it entered the critical section.


т.е. по идее они есть ref count защищенными, но хотелось бы уточнить..
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209511
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сомневаешься - затести.

Не совсем понял что подразумевается под ref counted.

Что касаемо приведенной цитаты, я ее так понимаю: "LeaveCriticalSection() вызывать однократно после каждого вызова EnterCriticalSection()". т.к. лишний вызов LeaveCriticalSection() может вызвать досрочное освобождение критической секции начатой в другом потоке.
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209589
зеленый админ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

тест - это как раз то, что влом было писать.
Хотя он был до неприличности короткий.

Под ref count (подсчет ссылок) я имел ввиду следующее:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
procedure TForm1.cxButton1Click(Sender: TObject);
VAR
  t : TThread;
  cs : TcriticalSection;
begin
  cs := TCriticalSection.Create;
  TRY
    cs.Enter;
    cs.Enter;
    cs.Leave;
    t := TThread.CreateAnonymousThread(
      PROCEDURE ()
      BEGIN
        cs.Enter;
        ShowMessage('Done');
      END);
    TRY
      t.Start;
      WaitForSingleObject(t.Handle, 1000);
    FINALLY
      t.Free;
    END;
  FINALLY
    cs.Free;
  END;

end;



убьет ли один Leave два Enter или только один из них? Оказалось только один из них, и юзверь мессагу никогда не удивит. Как-то так.
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209626
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
второй Enter не произойдет пока из первого не выйдет.
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209634
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал потом засомневался, решил затестить: заходит во вторую
Код: sql
1.
2.
3.
4.
5.
6.
	CRITICAL_SECTION CriticalSection;
	if(!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x00000400)) return 0;
	EnterCriticalSection(&CriticalSection);
	printf("enter 1 \n");
	EnterCriticalSection(&CriticalSection);
	printf("enter 2 \n");


результат
Код: sql
1.
2.
enter 1
enter 2


сейчас треды добавлю, посмотрю как Leave работает
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209637
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Эй, вы чего?
У Рихтера же однозначно сказано: " Если значения элементов структуры свидетельствуют, что ресурс уже захвачен вызывающим потоком, EnterCriticalSection обновляет их, отмечая тем самым, сколько раз подряд этот поток захватил ресурс... ".
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209639
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, привязка к потоку есть. Если честно думал что секции к потоку не привязаны.
тест
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
#include <windows.h>

CRITICAL_SECTION CriticalSection;

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
	printf("thread start\n");
	EnterCriticalSection(&CriticalSection);
	printf("thread work\n");
	LeaveCriticalSection(&CriticalSection);
	printf("thread end\n");
	return 0;
}


int main()
{
	if(!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x00000400)) return 0;
	EnterCriticalSection(&CriticalSection);
	printf("enter 1 \n");
	EnterCriticalSection(&CriticalSection);
	printf("enter 2 \n");
	CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL);
	Sleep(100);
	printf("leave 2 \n");
	LeaveCriticalSection(&CriticalSection);
	Sleep(100);
	printf("leave 1 \n");
	LeaveCriticalSection(&CriticalSection);
	Sleep(100);
	return 0;
}


результат
Код: sql
1.
2.
3.
4.
5.
6.
7.
enter 1
enter 2
thread start
leave 2
leave 1
thread work
thread end

...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209644
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже к потоку привязаны только Enter`ы, Leave уменьшает счетчик из любого потока.
тест
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
#include <windows.h>

CRITICAL_SECTION CriticalSection;

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
	printf("thread start\n");
	LeaveCriticalSection(&CriticalSection);
	EnterCriticalSection(&CriticalSection);
	printf("thread work\n");
	LeaveCriticalSection(&CriticalSection);
	printf("thread end\n");
	return 0;
}


int main()
{
	if(!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x00000400)) return 0;
	EnterCriticalSection(&CriticalSection);
	printf("enter 1 \n");
	EnterCriticalSection(&CriticalSection);
	printf("enter 2 \n");
	CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL);
	Sleep(100);
	printf("leave 2 \n");
	LeaveCriticalSection(&CriticalSection);
	Sleep(100);
	printf("leave 1 \n");
	LeaveCriticalSection(&CriticalSection);
	Sleep(100);
	return 0;
}


Результат
Код: sql
1.
2.
3.
4.
5.
6.
7.
enter 1
enter 2
thread start
leave 2
thread work
thread end
leave 1

...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39209665
MrCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так низзя : "If a thread calls LeaveCriticalSection when it does not have ownership of the specified critical section object, an error occurs that may cause another thread using EnterCriticalSection to wait indefinitely."
...
Рейтинг: 0 / 0
WIN: EnterCriticalSection/LeaveCriticalSection
    #39210025
зеленый админ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrCatЭй, вы чего?

Да с Enter более понятно , чем с Leave. По той же моей ссылке из микрософт

MSDNAfter a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution.


А вот про Leave они ничего не написали. Пришлось тестить... Боялся, чтобы не вышло как для Rollback для БД. Благо нет, подсчет ссылок работает.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Программирование [игнор отключен] [закрыт для гостей] / WIN: EnterCriticalSection/LeaveCriticalSection
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]