Windows Critical Section странное поведение - PullRequest
2 голосов
/ 19 января 2011

У меня есть две общие глобальные переменные

int a = 0;
int b = 0;

и две темы

// thread 1
for (int i = 0; i < 10; ++i) {
    EnterCriticalSection(&sect);
    a++;
    b++;
    std::cout << a " " << b << std::endl;
    LeaveCriticalSection(&sect);
}

// thread2
for (int i = 0; i < 10; ++i) {
    EnterCriticalSection(&sect);
    a--;
    b--;
    std::cout << a " " << b << std::endl;
    LeaveCriticalSection(&sect);
}

Код всегда печатает следующий вывод

1 1

2 2

3 3

4 4

5 5

6 6

7 7

8 8

9 9

10 10

9 9

8 8

7 7

6 6

5 5

4 4

3 3

2 2

1 1

0 0

Это довольно странно, похоже, что потоки работают последовательно.

Спасибо.

Ответы [ 3 ]

4 голосов
/ 19 января 2011

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

Однако вы можете активно вернуть управление, вызвав Sleep(0) после того, как оставите критическую секцию внутри цикла.

2 голосов
/ 19 января 2011

Выход из / в критической секции IMO в вашем примере настолько быстр, что другой поток недостаточно быстр для выполнения ввода в этот момент.

Попытайтесь поставить несколько (возможно, случайных) снов, чтобы замедлить код, чтобы увидеть желаемые эффекты.

Примечание: Время ожидания по умолчанию для EnterCriticalSection составляет около 30 дней (означает бесконечность), поэтому вы не можете ожидать, что эта функция истечет. И документация гласит:

Нет никакой гарантии относительно порядка, в котором потоки получат право владения критическим разделом, однако система будет справедлива для всех потоков.

1 голос
/ 31 мая 2012

Для меня это выглядит как тема, обсуждаемая в http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/980e5018-3ade-4823-a6dc-5ddbcc3091d5/ Пожалуйста, посмотрите пример от 28 июня 2006 г.

(к сожалению, я не могу найти оригинальную статью Microsoft, в которой говорится об изменении CriticalSection)

Не могли бы вы попробовать свой код в Windows XP?Что это показывает?

I догадывается , что операции ввода-вывода (cout) влияют на планирование аналогично вызову Sleep (), поэтому, начиная с Windows Vista, поток может вызвать голодание другихпотоки при выполнении ввода / вывода внутри CS.

...