Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите придумать способ синхронизации  (Прочитано 10701 раз)
0 Пользователей и 1 Гость смотрят эту тему.
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« : 02-08-2006 08:44 » 



Есть транспортная структура которая используется для обработки запросов сервером сваязи.
class CTrans
{
   
public:
   bool isComplite; //обрабока заверше
   HANDLE evAck;
   // Завершить обработку запроса в том виде как есть и отдать команду на отсылку ответа слиенту
   int Complete(void);
};



int CTrans::Complete(void)
{
   this->isComplite=true;
    SetEvent(this->evAck);
   return 0;
}


Структура сервера
1) «пайпы» объекты  поддерживающие связь с клиентами через сокет .
На каждого клиента по одному объекту , у каждого объекта 2 потока один  принимает и разбирает  входящий поток формирует  экземпляры  CTrans заполняет служебные поля
Устанавливает isComplite=0; в evAck заносится ид события на котором в WFSO вист второй поток ответственный за отправку ответов на запросы, помешает указатель в свободную ячейку массива и вызывает функцию маршрутизации(котрой передается указатель на экземпляр CTrans ) в результате работы которой  указатель  попадает в очередь одного из каналов. Второй поток сидит в WFSO на событии как только событие происходит он проходит по массиву и для всех CTrans у которых выставлен isComplite==1 формирует ответ и отправляет ответ затем удаляет объект из памяти.

2) «Каналы» крутятся в цикле выбирая по одному  CTrans из очереди выполняют запрос к прибору после чего вызывают CTrans::Complete() и удаляют указатель из свое очереди.


Проблема в том  что вызов CTrans::Complete() может произойти на любом этапе обработки и есть подозрение что периодически  второй поток «пайпа» успевает грохнуть экземпляр CTrans раньше чем произойдет выход из CTrans::Complete();

Есть идеи как можно этого избежать?


Записан

Да да нет нет все остальное от лукавого.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #1 : 02-08-2006 09:53 » 

PSD, вовесь мютек на входе.
я обычно использую boost::mutex
class CTrans
{
boost::mutex mutex_;   
public:
   bool isComplite; //обрабока заверше
   HANDLE evAck;
   // Завершить обработку запроса в том виде как есть и отдать команду на отсылку ответа слиенту
   int Complete(void);
};

int CTrans::Complete(void)
{
   boost::scoped_lock l(mutex_);
   this->isComplite=true;
    SetEvent(this->evAck);
   return 0;
}

CTrans::~CTrans()
{
   boost::scoped_lock l(mutex_);
   еще что-то чистим
}

соседний поток зависнит на
   boost::scoped_lock l(mutex_);
если кто-то сделал это раньше
mutex_ отпустится при выходе из области видимости l(mutex_) в данном случае из метода когда выйдем тогда и отпустим тоже можно сделать стандартными средствами винды вроде Critical Section и т.п.
Записан

Странно всё это....
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 02-08-2006 10:38 » 

Мне тоже приходило в голову использовать мютексы или события но вот в чем вопрос ... а ничего что одновоерменно в ситеме может присудствовать несколько дестяков тысяч объектов CTrans ?

Ведь число обектов ядра вроди как ограничено?
Записан

Да да нет нет все остальное от лукавого.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #3 : 02-08-2006 10:54 » 

PSD, мьютек в управляющие потоки
и крайний случай сделать его глобальным

сделай внутри CTrans флаг
в деструкторе
while(!complite_flag);

изменение флага в true
поставь перед выходом из complite
Улыбаюсь то же метод и без мьютексов.

или проверяй флаг из вне CTrans чтение/изменение флага должно быть тоже из вне и закрыто мьютексом который за пределами

CTrans c = new Ctrans;
 
  {
   boost::scoped_lock l(mutex_);
    c->complite;
  }

  {
   boost::scoped_lock l(mutex_);
    if(c->check())
      delete;
  }

как-то так

или еще хранить какой-то объект который будет указывать на последний CTrans для которого вызва complite и вызывать деструктор толко для тех объектов для которых complite вызван опять же обращение к подобному указателю закрыть мьютексом
« Последнее редактирование: 02-08-2006 11:03 от LogRus » Записан

Странно всё это....
Diletant
Помогающий

de
Offline Offline

« Ответ #4 : 06-08-2006 11:00 » 

Я правильно понял, что речь идет только о сихронизации двух потоков: потока приема данных и потока их обработки. Если так, то поток один поток просто должен ждать завершения другого потока по хэндлу потока. Т.е в CTrans::Complete(void) вставляешь WaitForSingleObject(hThread,...).

Цитата
Мне тоже приходило в голову использовать мютексы или события но вот в чем вопрос ... а ничего что одновоерменно в ситеме может присудствовать несколько дестяков тысяч объектов CTrans ?

Потоки - это ведь тоже объекты ядра. Такое количество потоков тебя не смущает?
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 07-08-2006 04:48 » 

Diletant, ты заблуждаешься, синхронизация поков не подразумевает их уничтожения.
гораздо чаще под синхронизация нужна для кореектного доступа к разделямым потоками данным
простой пример разделямый несколькими потоками объект, изменяет своё состояние вызовом какго-то метода, и объект будет потоко безопасным, если за время выполнения метода не изменится его состояние.
способов как обычно много
Записан

Странно всё это....
zubr
Гость
« Ответ #6 : 07-08-2006 05:57 » 

Можно и без мутексов обойтись, примерно как Diletant посоветовал:
Код:
if(WaitForSingleObject(hThread, 0)!=WAIT_OBJECT_0)
continue;//переход на следующую итерацию цикла
//код убивающий объект CTrans
Записан
Diletant
Помогающий

de
Offline Offline

« Ответ #7 : 07-08-2006 19:20 » 

Цитата
Diletant, ты заблуждаешься, синхронизация поков не подразумевает их уничтожения.
гораздо чаще под синхронизация нужна для кореектного доступа к разделямым потоками данным
простой пример разделямый несколькими потоками объект, изменяет своё состояние вызовом какго-то метода, и объект будет потоко безопасным, если за время выполнения метода не изменится его состояние.
способов как обычно много

В общем случае, это совершенно верно, но ведь в данном конкретном речь идет именно о двух потоках и о том, как при удалении объекта, создаваемом в одном потоке, дождаться завершения обрабтки данных другим потоком. Или я все-таки все не так понял?
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 08-08-2006 04:14 » 

Diletant, потоки данных не останавливаются. один примает данные и создаёт объект. один отдаёт данные и уничтожает объект. нужно синхронизировать время жизни объекта данных.
Записан

Странно всё это....
Diletant
Помогающий

de
Offline Offline

« Ответ #9 : 08-08-2006 20:06 » 

Я думал, что потоки - это части объекта. А тогда зачем огород с объектам ядра городить? При создании объекта создать две переменные: ПотокОдинПостСдал и ПотокДваПостСдал, и пока оба не станут нулями - уничтожать нельзя. Как менять переменные синхронно, в любой книжке написано.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #10 : 09-08-2006 04:38 » 

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



ладно это уже общение пошло, а не решение проблемы. PSD уже небось всё сделал.
Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines