Jump to content
Sign in to follow this  
Bernardo Vieira

Timer passa o valor errado

Recommended Posts

Bernardo Vieira

bom, eu consegui um codigo como base

#include <windows.h>
#include <stdio.h>

HANDLE gDoneEvent;

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
if (lpParam == NULL)
{
	printf("TimerRoutine lpParam is NULL\n");
}
else
{
	// lpParam points to the argument; in this case it is an int

	printf("Timer routine called. Parameter is %d.\n",
			*(int*)lpParam);
	if(TimerOrWaitFired)
	{
		printf("The wait timed out.\n");
	}
	else
	{
		printf("The wait event was signaled.\n");
	}
}

SetEvent(gDoneEvent);
}

int main()
{
HANDLE hTimer = NULL;
HANDLE hTimerQueue = NULL;
int arg = 123;

// Use an event object to track the TimerRoutine execution
gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == gDoneEvent)
{
	printf("CreateEvent failed (%d)\n", GetLastError());
	return 1;
}

// Create the timer queue.
hTimerQueue = CreateTimerQueue();
if (NULL == hTimerQueue)
{
	printf("CreateTimerQueue failed (%d)\n", GetLastError());
	return 2;
}

// Set a timer to call the timer routine in 10 seconds.
if (!CreateTimerQueueTimer( &hTimer, hTimerQueue,
		(WAITORTIMERCALLBACK)TimerRoutine, &arg , 10000, 0, 0))
{
	printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());
	return 3;
}

// TODO: Do other useful work here

printf("Call timer routine in 10 seconds...\n");

// Wait for the timer-queue thread to complete using an event
// object. The thread will signal the event at that time.

if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)
	printf("WaitForSingleObject failed (%d)\n", GetLastError());

CloseHandle(gDoneEvent);

// Delete all timers in the timer queue.
if (!DeleteTimerQueue(hTimerQueue))
	printf("DeleteTimerQueue failed (%d)\n", GetLastError());

return 0;
}

que para quem tiver curiosidade esta aqui http://msdn.microsoft.com/en-us/library/ms687003%28v=vs.85%29.aspx

mas tem um problema, esse codigo assim funciona perfeitamente, mas se eu retirar a partir de WaitForSingleObject a resposta vai ser diferente, en vez de passar "123" passa "2009494882" ou um numero assim parecido! Porque? bom, na verdade eu nao tiro neste script, eu so coloquei aqui assim para ser simples, porque no case eu coloco noutro script e o programa continua a executar outras funcoes e passados os 10 segundos aí sim, responde

Edited by Rui Carlos

Share this post


Link to post
Share on other sites
pikax

porque nao usas algo standard, como C++ 11, a parte de eventos e thread esta' boa

  • Vote 1

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Bernardo Vieira

obrigado pelo concelho mas eu nao encontrei nada

alias, encontrei sim, outras funcoes como SetTimer e KillTimer, mas nao consegui usa-la, depois encontei outra, SetWitableTimer, mas isso para o codigo e eu nao quero, na verdade nao achei nada, talvez porque tambem nao estou a fazer a pesquisa correta.

Podes ajudar-me mais um pouco, fico agradecido desde já :)

obrigado pelo concelho mas eu nao encontrei nada

alias, encontrei sim, outras funcoes como SetTimer e KillTimer, mas nao consegui usa-la, depois encontei outra, SetWitableTimer, mas isso para o codigo e eu nao quero, na verdade nao achei nada, talvez porque tambem nao estou a fazer a pesquisa correta.

Podes ajudar-me mais um pouco, fico agradecido desde já :)

Share this post


Link to post
Share on other sites
pikax

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Bernardo Vieira

eu encontrei muita coisa foi com a header chrono, mas o meu visual studio nao tem, na verdade acho que ele nao tem muita coisa de C++11 :|

agradeço imenso, mas nao me ajudou grande coisa, porque nos exemplos que tu deste o codigo é parado, mas eu nao quero parar a execucao, quero continuar, tipo o codigo que eu tenho acima tá bom ele so nao passa o valor correto. Mas esquecendo o codigo acima, imagina, eu inicio um programa, e ao iniciar, ele inicia um timer tambem (de 1 minuto por exemplo) mas o programa continua a executar, como se fosse um teste, tem perguntas e tens de ir respondendo e ao fim de um minuto (tempo do timer) o programa fecha! entendes? nao é nada disto que eu quero fazer mas é exatamente da mesma forma! (mas nao interessa muito estar a explicar o que queria fazer pq é para um servidor de SA-MP, mas a forma de fazer é igual)

Edited by Bernardo Vieira

Share this post


Link to post
Share on other sites
pikax

Qual e' a tua versao do Visual Studio?

Edited by pikax

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
pikax

o 2010 nao da' suporte ao C++11 sem ser em tr1... para teres um bom suporte de c++11 usa o Visual Studio 2012 Express


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Bernardo Vieira

pois, pensei nisso também, estou a baixar!

Depois vou tentar com um codigo que encontrei, se der certo volto cá para postar, senao tenho de arranjar outra forma. É que eu procurei em varios sitios e encontrei em alguns pessoas que diziam que queriam colocar um timer mas continuar a execucao do programa e todos que respondiam diziam para usar TimerQueue, que foi o que eu usei, e está certo, funciona correto, mas por alguma razao, nao me passa o valor correto!

Bem, muito obrigado desde ja :)

Share this post


Link to post
Share on other sites
pikax

podes explicar melhor o que realmente queres fazer?


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Bernardo Vieira

pronto, entao vou tentar explicar direitinho a ver se a gente se entende.

eu pretendo aprender C++ porque de todas as linguagens que usei foi a que gostei mais. E como tenho um servidor de SA-MP e podemos usar C++ vou aproveitar. Bem na verdade, para programar o servidor usa-se PAWN (praticamente igual a C) mas é single thread e isso faz com qua aumente a LAG no servidor, e como temos a possibilidade de usar C++ em plugins eu começei a apostar nisso á pouco tempo (porque C++ é multi thread e posso fazer muitas mais coisa) mas o sistema era um bocado limitado portanto começei á pouco

O que eu quero fazer, imagina, quando player entra no servidor, começa a jogar e é preciso ir salvando as coisas que ele ganha, sim, eu posso salvar no final de cada partida, mas imagina que por algum motivo o server cai (ou crasha) entao seria bom que de x em x tempo fosse atualizando a conta do player. Eu uso MySQL como base de dados, mas com isso nao tive problema, custou um bocado mas consegui, agora é na boa, mas o timer nao consigo, ou melhor, com o codigo que eu postei acima eu consigo, so que nao passa o parametero de playerid e eu preciso disso para dizer que estou a atualizar a tua conta ou a minha, entendes?

Edited by Bernardo Vieira

Share this post


Link to post
Share on other sites
Bernardo Vieira

desculpem, o double post, é so para dizer que já consegui! para quem quiser fica aqui o codigo

#include <iostream>
#include <Windows.h>
#include <thread>
DWORD WINAPI vaiThread(LPVOID args) {
Sleep(5000);//o codigo pára apenas neste processo, o outro continua a executar
static int repeticoes=0;
int* value = reinterpret_cast<int*>(args);
printf("\n no thread %d", *value);
if(!repeticoes) {
vaiThread(value);//vamos repetir esta parte
}
repeticoes++;
return 1;
}
DWORD WINAPI runThread(LPVOID args)
{
int* value = reinterpret_cast<int*>(args);
printf("\n in thread %d", *value);
return 1;
}
int main()
{
DWORD threadId;
DWORD idthread;
int valor=5;
int value = 10;
HANDLE hThread[2];
hThread[0] = CreateThread( NULL, 0, vaiThread, &valor, 0, &idthread);//cria um processo
hThread[1] = CreateThread( NULL, 0, runThread, &value, 0, &threadId);//cira outro processo
Sleep(11000);//os dois processo foram executados, entao vamos para o processo atual para ver o resultado dos outros
system("pause");
return 0;
}

e obrigado por me teres tentado ajudar ;)

Edited by Bernardo Vieira

Share this post


Link to post
Share on other sites
HappyHippyHippo

pequenas correções :

int main()
{
 DWORD threadId;
 DWORD idthread;

 int valor=5;
 int value = 10;
 int result;

 HANDLE hThread[2];

 hThread[0] = CreateThread( NULL, 0, vaiThread, &valor, 0, &idthread);//cria um processo
 hThread[1] = CreateThread( NULL, 0, runThread, &value, 0, &threadId);//cira outro processo

 Sleep(11000);

 // o thread principal não deverá terminar antes dos restantes
 // isto porque não sabes se ficas com thread's zombies mantendo a aplicação "viva"
 // comendo recursos do sistema onde terás de ir ao gestor de tarefas "matar" a aplicação

 // o que apresento a seguir não testa estes casos, mas já é um começo
 // deveria ter um timeout para o thread e "matar" os thread se algum deles ultrapassar o
 // timeout esperado para manter a aplicação limpa

 while(GetExitCodeThread(hThread[0]), &result) == STILL_ACTIVE) Sleep(100); // <---- esperar que o thread termine
 while(GetExitCodeThread(hThread[1]), &result) == STILL_ACTIVE) Sleep(100); // <---- esperar que o thread termine

 closeHandle(hThread[0]); // <---- limpeza
 closeHandle(hThread[1]); // <---- limpeza

 system("pause");
return 0;
}


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Bernardo Vieira

tu nao entendeste ! este Sleep(11000); é so para ver os outros funcionar! mais nada! sim é verdade que se calhar esquecime de terminar os outros Threads :|

mas foi só isso! eu nao preciso de estar a verificar se terminou "while(GetExitCodeThread(hThread[0]), &result) == STILL_ACTIVE) Sleep(100);" porque tenho certeza que sim, só mandei executar duas vezes, um total de 10 segundos, e a funcao principal espera 11!

ou achas que devo sempre usar isso para verificar porque existe a possibilidade de nao ter terminado ?

e já agora, sabes como se fazem esses timeout ?

Edited by Rui Carlos

Share this post


Link to post
Share on other sites
HappyHippyHippo

ou achas que devo sempre usar isso para verificar porque existe a possibilidade de nao ter terminado ?

o que achas ...

e já agora, sabes como se fazem esses timeout ?

int timeout = 5000, time = 0;

time = 0;
while(GetExitCodeThread(hThread[0]), &result) == STILL_ACTIVE && time < timeout)
{
 Sleep(100);
 time += 100;
}
if (time >= timeout)
{
 TerminateThread(hThread[0], -1);
}

deverá existir maneiras mais elegantes com timers a afins, mas esta deve ser mais simples de implementar

  • Vote 1

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Bernardo Vieira

tens um pequeno problema, o GetExitCodeThread tem 2 parametros, ou talvez esse parentises seja erro, eu fiz diferente aqui!

mas entao eu poderia logo terminar o thread usando TerminateThread(hThread[0], -1); certo? nao preciso estar a verificar se ele ainda está ativo. Imagina, tá a decorrer, quero terminar a execucao do programa agora, entao ele tem de parar agora. entao posso usar so TerminateThread(hThread[0], -1); ou estou enganado ?

Share this post


Link to post
Share on other sites
HappyHippyHippo

tens um pequeno problema, o GetExitCodeThread tem 2 parametros, ou talvez esse parentises seja erro, eu fiz diferente aqui!

lembra-te que o que uma pessoa apresenta aqui no fórum é de cabeça e sem qualquer tipo de teste

se o código aparece com um caracter a mais lá pelo meio, é algo que muito bem pode acontecer

mas entao eu poderia logo terminar o thread usando TerminateThread(hThread[0], -1); certo? nao preciso estar a verificar se ele ainda está ativo. Imagina, tá a decorrer, quero terminar a execucao do programa agora, entao ele tem de parar agora. entao posso usar so TerminateThread(hThread[0], -1); ou estou enganado ?

é má prático "matar" threads, é sempre melhor dar uma oportunidade que estes terminem


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Bernardo Vieira

sim eu sei, por isso que eu so disse que tinhas erro foi gritei desesperadamente "dá erroooo, e agoraa :O" :| eu participo noutro forum e acontece de tbm me enganar!

Ok! entendido. Muito obrigado entao :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.