Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Эксперимент с потоками и синхронизацией, кто как объяснит результаты? 
V
    Опции темы
Ibragim
Дата 21.12.2006, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Вот решил поеспериментировать, результаты удивили. Кто как может объяснить.
Идея такая. 
1. Есть глобальная переменная, в которую будем пытаться писать из двух потоков без синхронизации.
2. Есть два потока, унаследованы от TThread. В каждом классе есть свой счетчик, сколько раз именно ОН изменял переменную. 
3. Оба потока после создания в бесконечном цикле инкрементируют глобальную переменную и свой счетчик.
4. По нажатию кнопки "Остановить" оба потока -> Suspend, и выводим в столбик значение глобальной переменной, счетчика в объекте класса1, счетчика №2.

Результат: Несколько минут (проверял минут 10) работы машины не вызывает никаких сбоев, приблизительно счетчик1 = счетчик2, сумма счетчиков равна глобальной переменной, то есть оба потока не "зависли" и в среднем пополам доступились до глобальной переменной. НО ВЕДЬ ДОЛЖНА хоть когда-то возникать ситуация одновременного доступа! 

Почему так:
1. Мала вероятность одновременного обращения? Тогда, с тем количеством попыток записи переменной из двух потоков, я могу легко доказать, что для обчного приложения вообще не нужны никакие CriticalSection и тп. Достаточно bool-флага, "занято"/"свободно". Вероятность одновременного доступа к этому флагу будет такова, что возникать будет раз в 10000 лет, при "обычной" организации приложения. (Там же не только в цикле попытки записи будут!).

2. Глобальная переменная защищена? Не вопрос, сделал третий класс, у него переменная - член класса, повторил опыт. То же самое, все работает.

Кто просветит?

Код
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SyncObjs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

ThreadA = class(TThread)
  s: int64;
  procedure Execute; override;
end;

ThreadB = class(TThread)
  s: int64;
  procedure Execute; override;
end;

var
  Form1: TForm1;
  ta: ThreadA;
  tb: ThreadB;
  y: int64;

implementation


procedure ThreadA.Execute;
begin
  s := 0;
  while 1=1 do
  begin
    Inc(s);
    Inc(y);
  end;
end;

procedure ThreadB.Execute;
begin
  s := 0;
  while 1=1 do
  begin
    Inc(s);
    Inc(y);
  end;
end;


{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  y := 0;
  ta := ThreadA.Create(false);
  tb := ThreadB.Create(false);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ta.Suspend;
  tb.Suspend;
  Edit1.Text := IntToStr(y);
  Edit2.Text := IntToStr(ta.s);
  Edit3.Text := IntToStr(tb.s);
end;

end.

PM MAIL   Вверх
KEM
Дата 21.12.2006, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 152
Регистрация: 28.1.2005

Репутация: нет
Всего: 2



Мне кажется всё же, между созданием одного класса и другово проходит процессорное время, которое и даёт разницу в доступе к переменной, плюс фактор занятости процессора в тот или иной момент, думаю что смоделировать такую ситуацию будет очень проблемно, попробуй создать эти 2-а потока одновременно, из идентичных но независимых источников. ИМХО
Код

  ta := ThreadA.Create(false);
  tb := ThreadB.Create(false);



--------------------
Мы растворяем сознание жизни, реальностью стал бешеный ритм...
PM MAIL   Вверх
Ibragim
Дата 21.12.2006, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Цитата(KEM @  21.12.2006,  00:54 Найти цитируемый пост)
между созданием одного класса и другово проходит процессорное время


Проходит-проходит, кто ж спорит. А дальше? Оба потока "крутят циклы", пока их не прервут. Вот здесь-то и должен быть глюк! Какая разница, с каким интервалом по времени они создаются/удаляются. Все равно львиную часть времени они работают ОДНОВРЕМЕННО.
PM MAIL   Вверх
KEM
Дата 21.12.2006, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 152
Регистрация: 28.1.2005

Репутация: нет
Всего: 2



Цитата

Все равно львиную часть времени они работают ОДНОВРЕМЕННО

Атнють
 
Цитата

плюс фактор занятости процессора в тот или иной момент

приоритеты никто ведь не отменял

Это сообщение отредактировал(а) KEM - 21.12.2006, 01:31
--------------------
Мы растворяем сознание жизни, реальностью стал бешеный ритм...
PM MAIL   Вверх
Ibragim
Дата 21.12.2006, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Цитата(KEM @  21.12.2006,  01:31 Найти цитируемый пост)
Атнють


Поясни, неочевидно.


Цитата(KEM @  21.12.2006,  01:31 Найти цитируемый пост)
приоритеты никто ведь не отменял


Ну и? У обоих по умолчанию tpNormal
PM MAIL   Вверх
aktuba
Дата 21.12.2006, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Потоки работают не одновременно - каждому потоку предоставляется определенный промежуток тактов процессора. Запись значения в переменную - одно действие, которое явно занимает меньше одного такта. Поэтому у тебя и нет глюков. А вот попробуй таким способом что-нибудь отрисовывать на форме и получать доступ к базе (короче, выполнить любое действие, которое не укладывается в один такт) и получишь замечательные =) глюки...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Ibragim
Дата 21.12.2006, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Отлично. То есть одну целочисленную переменную МОЖНО ВСЕГДА писать без синхронизации.
Зачем тогда объект TCriticalSection?
Давайте всегда вместо него использовать bool-переменную - флаг свободно/занято. Ни тебе создания объекта, ни подключения SyncObjs и так далее...


PM MAIL   Вверх
aktuba
Дата 21.12.2006, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата

Отлично. То есть одну целочисленную переменную МОЖНО ВСЕГДА писать без синхронизации.
Зачем тогда объект TCriticalSection?
Давайте всегда вместо него использовать bool-переменную - флаг свободно/занято. Ни тебе создания объекта, ни подключения SyncObjs и так далее...


Нет, то, что сказано выше, не означает, что при использовании одной переменной глюков не будет никогда. Рано или поздно - все-равно проявятся. Например на двуядерной машине - там потоки действительно работают параллельно. А насчет bool-переменной - если шутишь, так хоть улыбнись =). Зачем создавать формы, если можно делать программы без форм? =)


--------------------
user posted image
PM MAIL WWW Skype   Вверх
W4FhLF
Дата 21.12.2006, 08:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



Ibragim, всё собственнео уже сказали, но тут действительно никаких ошибок не возникнет, причём никогда, потому как оба потока записывают. 
Наименьшей единицей управления в системе исполнения является как раз поток, т.е. в один момент времени может выполняться только один поток, от этого никуда не уйдёшь и никак не переделаешь. Каждый поток выполняется на процессоре определённый промежуток времени, этот промежуток называется квантом потока, управление квантами, их величиной и приоритетами потока осуществляет планировщик, который и определяет какой поток нуждается в исполнении больше всего, а какой меньше и т.п. Поэтому как бы одновременно по-твоему потоки не работали, с точки зрения процессора запись происходит через чудовищно большие промежутки времени и никакой ошибки совместного доступа в твоём случае не будет никогда. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Matematik
Дата 21.12.2006, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

Репутация: 17
Всего: 50



Хм...
http://forum.vingrad.ru/topic-60076.html Глава 3. Основы синхронизации.
+ см. ф-и InterlockedXXX
PM MAIL WWW ICQ   Вверх
Snowy
Дата 21.12.2006, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Ну прямо как дети.
- А я всегда дорогу на красный свет перебегаю и ни разу ещё под машину не попал...
Что за ерунду вы тут обсуждаете?
Читайте Рихтера и умнейте smile
PM MAIL   Вверх
Sansa
Дата 21.12.2006, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 173
Регистрация: 18.10.2006
Где: Королев

Репутация: 3
Всего: 6



Snowy, очень точное сравнение (про светофор). 
На данной конкретной машине, в течение указанного количества времени, с указанным алгоритмом может ничего и не произойти, но НИКТО не даст гарантии, что при изменении одного из условий (а я привел лишь малую их часть) ситуация не изменится.
--------------------
- Здравствуйте, я Ваш патологоанатом
PM MAIL ICQ   Вверх
Ibragim
Дата 21.12.2006, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 28.9.2004
Где: Киев

Репутация: нет
Всего: нет



Ну ок.... Кое-как убедили smile 

Цитата(aktuba @  21.12.2006,  01:59 Найти цитируемый пост)
если шутишь, так хоть улыбнись =)


Шучу-шучу.... smile smile smile 

PM MAIL   Вверх
Alexeis
Дата 21.12.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Я тоже недавно делал такой опыт и меня тоже удивил такой результат, но тут я думаю есть еще особенность связанная с архитектурой процессора. Даже на одноядерном процессоре имеются много конвейеров + оптимизация. Для современного процессора в данной ситуации возможно операция является неделимой, ведь обращение к ОЗУ является для него медленной операцией.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
W4FhLF
Дата 21.12.2006, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 6
Всего: 121



Цитата

Я тоже недавно делал такой опыт и меня тоже удивил такой результат


Чем? Ты же сам говоришь об архитектуре процессора, которая исключает возможность ошибок в данном случае и тут же этому удивляешься.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0603 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.