| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Задержка выполнения функции |
| Автор: ApolloKiD 14.3.2013, 12:37 | ||
| Доброго времени суток. После долгого поиска в интернете, пришёл сюда за помощью. Дело в том что, есть функция, в которой нужно остановить время, по началу пробовал циклом, но цикл останавливает время во всём процессе, тем самым другие функции не могут выполнить свою работу, пока цикл не закончится. Пример:
Пробовал с критическими секциями, но что-то не получается. Буду благодарен любым советам. Заранее спасибо. |
| Автор: ApolloKiD 14.3.2013, 14:02 | ||
| Благодарю за ответ. А есть способ без потоков? Например как с критическими секциями:
Но к сожалению, этот способ не работает, критическую секцию он обходит всё равно и идет дальше, не смотря на то, что он должен остановится. Или я не так понял работу критических секций. |
| Автор: feodorv 14.3.2013, 14:37 |
А зачем критические секции без потоков? Не ясна структура Вашей программы. Она однопоточная, и если вы приостановите выполнение этого потока в какой-то функции, то, естественно, приостановится весь поток. Но Вам этого не надо, а надо что-то другое. Что делают другие функции в те моменты, когда Вам хочется приостановить время? Как вообще вызывается proc2, которая должна "пробуждать" приостановленную Proc0? Очень многое можно сделать, находясь рамках одного потока, но тогда Вы обязаны соответствующим образом продумать схему возникновения и обработки возникающих событий. А эта схема совершенно не ясна. |
| Автор: ApolloKiD 14.3.2013, 15:34 | ||
| Proc2() вызывается при принятии данных. Вот как всё выглядит на самом деле:
|
| Автор: baldina 14.3.2013, 16:42 | ||
| ApolloKiD, раз это асинхронный ввод/вывод, одной функцией не выйдет. при асинхронной обработке одна чать программы посылает запрос и устанавливает обработчик (функцию), срабатывающую на прием данных. придется разбить код Proc0 на две части: отправка данных и получение данных. как именно это делать зависит от того, чем (какой библиотекой/функциями) вы пользуетесь для отправки/получения Добавлено через 2 минуты и 45 секунд если не вдаваться в подробности, ваш код должен быть переписан примерно так:
|
| Автор: volatile 14.3.2013, 18:17 |
| ApolloKiD, я так понял у вас приложение однопоточное. Не ясно только куда/от куда вы посылаете/прнимаете данные. Другому приложению, чтоли? (походу, если по сети, то тоже значит что другому приложению) Если все происходит внутри одного приложения, и оно однопоточно, то вообще ничего не надо. Нужно просто правильно организовать последовательность вызовов. |
| Автор: k0rvin 14.3.2013, 19:04 | ||
Ниче не понял. Наверное так, например:
|
| Автор: ApolloKiD 14.3.2013, 22:19 | ||
| baldina, WinSock. volatile, Да, вы правильно поняли, другому приложению. k0rvin, Так не пробовал, потому что данные сначала попадают на протокол и там идет функция принятия данных. Пример:
|
| Автор: volatile 14.3.2013, 23:50 |
| ApolloKiD, не вникая глубого, скажу имхо, Проще всего вам в данном случае сделать второй поток, и всю функцию ожидания ответа запустить в нем. Если не хотите ни в какую другой поток, придецца переделывать приложение конкретно. Потому что у вас все не так. Нужен цикл обработки сообщений (или что-то в этом роде), нужны быстрые обработчики этих сообщений, т.е. отдельные функции: послал, принял, обработал, и т.д. Никакая из них ничего не должна ждать. Тот обработчик, которого у вас ждут, при завершении просто посылает сообщение, это сообщение обабатываецца, то есть по факту готовности, а не ожидая у моря погоды. |
| Автор: baldina 15.3.2013, 17:19 |
| ApolloKiD, установление соединения со стороны сервера выглядит так: 1. подготовка соединения, начало прослушивания create socket(protocol) -> bind (port) -> listen() 2. установка соединения (инициированного клиентом) accept() в этот момент сервер начинает обслуживает данное соединение. что бы дать ему возможность отвечать и на другие запросы, нужно либо мультиплексировать обслуживание (асинхронный ввод/вывод), либо (проще, но накладнее) создать отдельный поток для данного соединения. 3. send()/recive() для данного соединения со стороны клиента чуть иначе, но похоже 1. подготовка соединения create socket(protocol) 2. установка (инициация) соединения сonnect() в этот момент клиент готов читать и писать. если параллельно с обменом данными нужно делать другую работу (например, данные приходят время от времени, и нужно их отображать по мере поступления, "в фоне"), recive() нужно делать либо в отдельном потоке, либо асинхронно. 3. send()/recive() для данного соединения для асинхронного обмена можно использовать 1. pool() или select(), которые могут проверить состояние сокета(ов) без блокировки (через таймаут) 2. неблокирующий режим. для перевода в этот режим используется ioctlsocket(). теперь recv() будет не блокировать поток, а возвращать управление сразу (с ошибкой, если данные еще не пришли) 3. WSAAsyncSelect - вариант неблокирующего select() для оконных приложений, факт готовности приема/отправки данных передается через очередь сообщений windows |
| Автор: feodorv 15.3.2013, 21:39 | ||
Или WSAEventSelect/WSAWaitForMultipleEvents для не оконных))) |
| Автор: baldina 15.3.2013, 22:41 |
| виноват. WSAAsyncSelect |