Как сделать аналог прерывания?
Запрограммировать его на переход в сигнальное состояние через заданное время
Запрограммировать его на переход в сигнальное состояние через заданное время
А на событие нельзя повесить? Ну типа событие "на сокет пришло что-то", вроде как обычный poll/select есть на всех операционках.
Который как идеально подходит под условие.
А что за событие ты предлагаешь? случайное событие? а вдруг оно не придет?
в вызываемой функции запускаю другой поток, где запускаю рабочую функцию.
в основном потоке кручу while, смотрящий, не появилось ли что-либо в буле answerFetched. Если появилось, то функция завершилась и мы берем данные и возвращаем их, если не появилось по истечению времени - килять тот поток и возвращать nil.
Плюс: интерфейс остался в рамках одного метода, без оповещений и сигналов.
Минус: основной поток грузится этим бессмысленным whileом.
Покатит такой подход?
активное ожидание, его лучше избегать.
Нет. Это В смысле
while !answer) && (a<FireTIme
{
a=[[NSDate alloc] init].timeIntervalSince1970;
}
Заменить на
while !answer) && (a<FireTIme
{
sleep (0.1);
a=[[NSDate alloc] init].timeIntervalSince1970;
}
Ну это все равно хуже, чем ожидание push-нотификации, но лучше, чем первый вариант.
В основном потоке
InitializeWaitableTimer(hEventTimeout, OPERATION_TIMEOUT) //инициализация таймера
CreateThread //создание дополнительного потока
EventIndex = WaitForMultipleObjects([hEventThreadReady, hEventTimeout)], ....); //Ожидание события, которое наступит раньше
В коде потока
a = CallHeavyFunction(..) //вызов той самой долгой функции
SetEvent(hEventThreadReady, TRUE); //установка объекта в сигнальное состояние
Кстати, в данном простейшем случае можно вообще обойтись функцией WaitForSingleObject и без таймера, т.к. в этой функции есть свой внутренний таймаут
Это всё windows-specific, а у автора obj-c
поищи в доках по слову NSTimer
Да... навскидку аналога waitformultiply под iOS я не вижу, хотя о чем-то таком я и мечтал
А waitforsingle с таймаутом там тоже отсутствует? А то ведь можно было бы просто подождать завершения потока.
в Хайдерабаде с такими скилами по двести программистов в день выпускается
> The correct way to stop your thread executing is to ask it nicely to stop executing.
и
> cancel method only informs the thread that it is cancelled ... It's then the responsibility of the thread itself to check this and exit.
Да... навскидку аналога waitformultiply под iOS я не вижу, хотя о чем-то таком я и мечталselect ? Или iOS POSIX-совместимая только на словах?
Ну и да, беглый гуглинг подсказал, что по крайней мере сигналы там имеются. Организуй рабочему треду сигнал в нужный момент, а в обработчике сигнала прибей тред. Не?
ЗЫ: функция alarm (SVr4, POSIX.1-2001, 4.3BSD) как раз нужна для организации таких сигналов, а signal (POSIX.1-2001) для установки обработчика.
ЗЗЫ:
пример на C под обычный Linux, под iOS должно быть аналогично, если сигналы работают так же.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
volatile int x = 0;
void useless_work(void)
{
while (1) {
x++;
}
}
void sighandler(int sig)
{
printf("%d\n", x);
exit(0);
}
int main(void)
{
signal(SIGALRM, sighandler);
alarm(2);
useless_work;
return 0;
}
Причем там вроде и делегаты неплохо поддерживаются, непонятно, зачем треды вообще нужно убивать.
это слишком жёстко. в обработчике сигнала лучше выставить флаг прерывания.
@protocol workDelegate
-(void) answerFetched: (id) answer;
@end
...
-(void) doWork
{
answer=doReallyWork;
[self performSelectorInMainThread:@selector(Notifier) withObject: nil];
}
-(void) Notifier
{
if (needed) {[self.delegate answerFetched:answer]; needed=0;}
}
-(void) mainFunction: (double) timeout
{
needed=1;
[self performSelectorInBackground:@selector(doWork) withObject:nil];
[self performSelectorInBackground:@selector(Notifier) withObject:nil afterDelay:timeout];
}
В крайнем случае, если есть какие-то существенные ограничения, задается конкретный поток для doWork, который радостно уничтожается по таймауту.
Но мне бы очень хотелось, чтобы ответ возвращался именно вызываемой функцией. Поэтому и приходится прибегать к такому кошмару.
Оставить комментарий
Anna551
Есть функция, которая возвращает результат через нефиксированное время (0-120 секунд)Как аккуратно (без рамножения таймеров) можно реализовать "таймаут" для нее? То есть, чтобы не позднее чем через фиксированное время возвращался, быть может пустой, результат?
Если что, язык - Objective C.