Дмитрий Радищев (dibr) wrote,
Дмитрий Радищев
dibr

синхронизация

     На работе пишем счётную программу, обсчитывающую нечто в двух нитях. Нити должны быть синхронизованы - одна не должна обгонять другую. Сделали так: ("псевдокод" на Си):
volatile int lock;

main()
{
 lock=0;
 create_thread(&thread1);
 create_thread(&thread2);
 {ждём и время от времени рисуем графики}
}


thread1()
{
while(1)
 {
  {что-то считаем}
  lock++;
  while(lock==1);
  lock=0;
 }
}

thread2()
{
while(1)
 {
  {что-то считаем}
  lock++;
  while(lock==1);
  lock=0;
 }
}

     Идея ясна: первая нить, досчитав, увеличивает lock, он становится равен 1, нить встаёт в цикл while и ждёт. Вторая нить, досчитав, увеличивает lock, он становится равен 2, нить сбрасывает lock в 0 и идёт на второй круг, первая нить, увидев 0, тоже идёт считать дальше. При желании это легко масштабируется на N нитей, заменой while(lock==1); на while(lock!=0 && lock!=N);. Да, я понимаю. что while(); грузит ядро на 100% - но разница в скорости работы нитей небольшая, да и ядро это всё равно простаивало бы, в ожидании соседней нити. Да, я знаю что "системными функциями было бы надёжнее", но нити крутятся очень быстро, вызывать относительно тяжеловесные системные функции как-то не хочется, такой вот spinlock побыстрее будет.
     Так вот. После нескольких десятков-сотен тысяч "оборотов" обе нити "зависают". Зависают в while(lock==1);. Почему - я так и не понял, volatile вроде не забыл, "гонок" я не вижу. Кто-нибудь может понять, на какие грабли мы тут наступили? Компилятор - какой-то не очень свежий borland C++ builder, какой точно - на работе посмотрю, навскидку не помню.
     Вопрос сейчас уже теоретический - блокировку переписали по другому, "так что работает", а поскольку задача счётная и "для себя", то и пофиг, лишь бы работало. Но чисто теоретически - какого фига? Что тут может быть, lock++ на самом деле неатомарный, или я гонки где-то не заметил?...
Subscribe
  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 32 comments