Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > функция должна ждать команды а как ?


Автор: Dubinsky 22.8.2005, 17:37
есть некая функция , при обращении к которой она должна ждать когда ей дадут команду и только после этого завершить своё выполнение, как это реализовать ?
Код

void mywaitfunc(void)
{
   uslovie = false;
   while(true)
   {
      if (uslovie) break;
   }
}
//==============
//где то на другом краю кода (для примера на самом деле ждать условие надо будет н
//не от визуальных компонентов а из нета но смысл то один и тотже)
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  uslovie = true;
}


это работает но цикл , жрёт проц на все 100 , как по-другому можно ждать ?

Автор: Orlan 22.8.2005, 17:46
Создать другой поток (thread) и в нем выполнять эту функцию. Внутри цикла опрашивать переменную uslovie, которая может поменяться в основном (пользовательском) потоке.

Автор: srd 22.8.2005, 17:47
Если я правильно понял, что тебе надо, то читаем документацию на тему CreateThread/WaitForSingleObject/CreateEvent

Автор: Orlan 22.8.2005, 17:53
В С++ Builder-e кажется есть класс TThread, можно покопать еще в этом направлении.
Если используется в проекте стандартная библиотека С, то вместо CreateThread надо использовать _beginthread (Он есть в ВизуалСи, и по идее должен быть и в билдере)

Автор: Dubinsky 22.8.2005, 17:54
уффф думал обойтись ка то без потоков ... ну да ладно ... попробую ...
Добавлено @ 17:55
используется Билдер кстати ...

Автор: mr.Anderson 22.8.2005, 17:56
А я могу предложить свою версию? Я не тестировал этот код, но вдруг получится...
Код

#include <windows.h>

int sleep=0;

void YOUR_WAIT_FUNC(void)
{
//Что-то там делаем
//...
//Когда надо ждать, пишем
do Sleep(1) while(!sleep);
}
//На другом конце провода (то есть программы :))
...
//Если что-то происходит, то
sleep=1;

Еще раз повторю, это мое предположение...

Автор: Orlan 22.8.2005, 17:57
Без потоков тоже можно, внутри цикла ты должен организовать обработку приходящих сообщений (messages). Только это можеть негативно сказатся на производительности цикла.
Ксати
Цитата
... но цикл , жрёт проц на все 100 ...

жрёт проц на все 100 это значит работает, не простаивает smile

Автор: Dubinsky 22.8.2005, 18:05
цикл не делает ничего ! он ждёт , после чего по сигналу , по заранее известному адресу (событие типа : Ахой , пришли новые данные) считывает данные. жрёт потому что как проц свободен он сразу оп , и проверять что там у нас с переменной ...

как я понял мне следует :

1 создать семафор :
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,// NULL ?
LONG lInitialCount, // initial count // 0 ?
LONG lMaximumCount, // maximum count // 1
LPCTSTR lpName // pointer to semaphore-object name // WTF ???? это его имя ?
);

2 ждать его изменения . DWORD WaitForSingleObject(

HANDLE hHandle, // handle of object to wait for - семафор хэндл ?
DWORD dwMilliseconds // time-out interval in milliseconds ну тут всё ясно
);

так получается ?

Автор: Orlan 22.8.2005, 18:19
Если сигнал подается другим потоком или процессом, то можно и так
Семафорами я не пользовался, не знаю
Можно через события делать (CreateEvent)

Автор: Dubinsky 22.8.2005, 18:24
а разве процесс не связан с .ехе файлом , разве он не станет светится в Windows Task Managere ?

Автор: Orlan 22.8.2005, 18:35
Я имел ввиду, что если тут участвует всего один поток, то например пользователь не сможет нажать кнопку, после которой начнутся выдаватся новые данные. Если же источник событий не пользователь, а другой поток или процесс, то таких проблем не будет.
ликбез:
экзешник - это просто файл на диске, а процесс - это запущенный экзешник, потоки - это то, что выполняется на процессоре, процесс состоит из потоков и глобальных данных.

Автор: Dubinsky 22.8.2005, 18:51
у меня в принципе не нужно чтоб юзер жал там что-то , просто он нажимает ОК , посылается инфа на сервер ,ждётся ответ (waitForSingleObject), обратно получается инфа , срабатывает событие onClientRead() (вот тут то самое интересное , сработает ли ? если уже ждётся ? waitForSingleObject'ом ) , и идём дальше ...

ладно до завтра ... надеюсь проверю я эти семафоры ...

Автор: Orlan 23.8.2005, 09:48
Цитата(Dubinsky @ 22.8.2005, 18:51)
у меня в принципе не нужно чтоб юзер жал там что-то , просто он нажимает ОК,

По сложности это одно и то же, это некая реакция пользователя.
Цитата(Dubinsky @ 22.8.2005, 18:51)

посылается инфа на сервер ,ждётся ответ (waitForSingleObject), обратно получается инфа , срабатывает событие onClientRead() (вот тут то самое интересное , сработает ли ? если уже ждётся ? waitForSingleObject'ом ) , и идём дальше ...

Если использутся сокеты, то лучше использовать WSA функции, WSASelect или их аналог от Борланда (если есть). Уведомление о пришедших данных с сервера поступят в оконную процедуру обработку сообщений и можно будет реализовать без потоков и без функций работы с событиями, семафорами и прочими функциями синхронизации.

Автор: Dubinsky 23.8.2005, 11:04
да я решил проще :

Код

// user nazhal knopku
if (WaitFrm->ShowModal() ==mrOk) // pokazivaem formu tipa "zhdite otveta.." zakrit' ee neljzja
{
    // vse ok rabotaem
}else
{
   // fak oshibka
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
// gde to na drugom konce koda
{
   //gde to v obrabotchike soobschenij
...
   WaitFrm->ModalResult = mrOk;
}


вот вопрос всё как бы неплохо даже получилось , но мучает вопрос а как сделать подобие ShowModal() ?Чтоб переменную поменял и хоп , всё пошло дальше , а когда вызываем ShowModal() прога работает а не спит как WaitSingleObject() ?

Автор: Orlan 23.8.2005, 14:13
Цитата(Dubinsky @ 23.8.2005, 11:04)
да я решил проще ...

Это обычное использование модальных окон, странно что вообще тогда возникили вопросы.
Цитата(Dubinsky @ 23.8.2005, 11:04)
вот вопрос всё как бы неплохо даже получилось , но мучает вопрос а как сделать подобие ShowModal() ?Чтоб переменную поменял и хоп , всё пошло дальше , а когда вызываем ShowModal() прога работает а не спит как WaitSingleObject() ?

Надо принудительно закрывать форму WaitFrm из другого потока или из обработкичка сообщений этой формы.

Автор: chaos 24.8.2005, 05:55
Цитата(Dubinsky @ 22.8.2005, 17:37)
есть некая функция , при обращении к которой она должна ждать когда ей дадут команду и только после этого завершить своё выполнение, как это реализовать ?
Код

void mywaitfunc(void)
{
   uslovie = false;
   while(true)
   {
      if (uslovie) break;
   }
}
//==============
//где то на другом краю кода (для примера на самом деле ждать условие надо будет н
//не от визуальных компонентов а из нета но смысл то один и тотже)
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  uslovie = true;
}


это работает но цикл , жрёт проц на все 100 , как по-другому можно ждать ?

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

Автор: Dubinsky 24.8.2005, 12:26
так я сразу и сделал , работает и ничего бы если бы в момент ожидания проц не был бы загружен на все сто !ну естественно это же цикл ...Ну по уму то как то по типу сендмесссидж - ресивмессидж должно пахать !

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)