Тема: Mail.ru SMS sender
Показать сообщение отдельно

  #30  
Старый 18.03.2010, 13:29
greki_hoy
Познающий
Регистрация: 04.03.2010
Сообщений: 32
Провел на форуме:
32525

Репутация: 23
По умолчанию

Gar|k как думаеш это пдойдет для асинхронных ответов серверу ?
отбработки ошибок нет для наглядности

Код:
typedef struct THREAD_INFO
{
	CONST PCHAR pMsg;
	HANDLE hCompleteInit;
} THREAD_INFO, *PTHREAD_INFO;

DWORD WINAPI SendThread(PTHREAD_INFO th)
{
	SOCKET s;
	PCHAR pMsg = malloc(strlen(th->pMsg)+1);
	strcpy(pMsg, th->pMsg);
	SetEvent(th->hCompleteInit); /* SendMsg выходиь из ожидания и завершается */
	s = conct(MmpAddr); /* connect */
	send(s, pMsg, strlen(pMsg), 0);
	free(pMsg);
	closesocket(s);
	return ERROR_SUCCESS;
}

VOID SendMsg(CONST PCHAR pMsg)
{
	HANDLE hThread;
	THREAD_INFO th = {pMsg};
	th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
	hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL);
	WaitForSingleObject(th.hCompleteInit, INFINITE);
	CloseHandle(th.hCompleteInit);
	CloseHandle(hThread);
}
идея такая чтоб если надо часто отправлять ответы количество одновременно работающих потоков увеличивалось все равно они все на вводе выводе приостановятся чтоб отправлять за раз много ответов а когда запросы нечастые нет ни одного потока
крутил крутил как сделать получилось это затраты на создание структур ядра потока и помещение его в очередь небольшие но все равно мне не нравится решение с постоянным созданием потоков сначал думал держать поток на событии но потом прикинул что мне надо например 10 потоков отправляли одновремено 10 событий ?
1 если собитые то или один поток проснется если с автосбросом или все если с ручным сбросом один если просыпатся будет неподходит так как отправка тогда не асинхронно будет выполнятся все тоже не пойдет если я передаю один запрос всего в минуту да и вот еще что допустим из какого то потока вызов SendMsg("MRIM_CS_HELLO"); так как вызов асихронный то она вернет управление и выйдет из функции ее вызывавшей буфер разрушится когда поток получит время начнет отсылать и прочитает из стека черти что поэтому пришлось сделать так
тут блокируем вызывабщий поток пока поток когда получит время не скопирует себе строку в кучу
Код:
th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
hThread = CreateThread(NULL, 0, SendThread, &th, 0, NULL);
WaitForSingleObject(th.hCompleteInit, INFINITE);
а поток когда проснется первым делом скопирует строку
Код:
PCHAR pMsg = malloc(strlen(th->pMsg)+1);
strcpy(pMsg, th->pMsg);
SetEvent(th->hCompleteInit);
маякнет вызывающему потоку что он закончил тот выйдет из вызова
SendMsg("MRIM_CS_HELLO");
и можно уже не опасатся из какого контекста вызывалась функция фактически только задержка на событии для копирования строки получается но мне это не нравится как то есть идеи как лучше отправку организовать ?
еще вариант с пулом поколдовать там хоть не надо создавать треды так часто
QueueUserWorkItem
в коде фактически придется только заменить CreateThread на QueueUserWorkItem
наверно эффективней должно быть хоть потоки завершатся не будут
набрел на твою статью решил поигратся с протоколом )))
кстати запости заголовок пакета которые отправляются перед сообщением который а то у меня маил агентов нет а ставить че то как то не очень то и надо ))
фактически вот сразу попробовал решение с пулом потоков вот что получилось

Код:
typedef struct THREAD_INFO
{
	CONST PCHAR pMsg;
	HANDLE hCompleteInit;
} THREAD_INFO, *PTHREAD_INFO;

DWORD WINAPI SendThread(PTHREAD_INFO th)
{
	SOCKET s;
	PCHAR pMsg = malloc(strlen(th->pMsg)+1);
	strcpy(pMsg, th->pMsg);
	SetEvent(th->hCompleteInit);
	s = conct(MmpAddr);
	send(s, pMsg, strlen(pMsg), 0);
	free(pMsg);
	closesocket(s);
	return ERROR_SUCCESS;
}

VOID SendMsg(CONST PCHAR pMsg)
{
	THREAD_INFO th = {pMsg};
	th.hCompleteInit = CreateEvent(NULL, FALSE, FALSE, NULL);
	QueueUserWorkItem(SendThread, &th, 
		WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION);
	WaitForSingleObject(th.hCompleteInit, INFINITE);
	CloseHandle(th.hCompleteInit);
}
работает много параллельных запросов из пула данные тоже корректно на событии
копируются вызывающий поток который хочеит отправить сообщение ждет только
пока потоку в пуле выделится время он скопирует пакет себе в память и тут же освобождает поток который хочет отправить сообщение
уже что то ))

есть мысли как сделать лучше ?))
 
Ответить с цитированием