digitalmars.D.learn - Implementing a timer using threads
↑ ↓ ← → Dennis Kempin <dennis xardias.net> writes:
Hi,
i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):
class Timer: Thread
{
int run()
{
while(true)
{
this.wait(1000); // wait one second
writefln("one second passed");
}
return 0;
}
}
But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).
regards
Dennis
↑ ↓ ← → Heinz <billgates microsoft.com> writes:
Dennis Kempin Wrote:
Hi,
i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):
class Timer: Thread
{
int run()
{
while(true)
{
this.wait(1000); // wait one second
writefln("one second passed");
}
return 0;
}
}
But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).
regards
Dennis
You could insert a block of asm code. Look here
http://www.digitalmars.com/d/iasm.html for valid opcodes.
Here http://www.acm.uiuc.edu/sigmil/talks/shellcode/sleep.asm is an approach.
This method is platform independant but not architecture independant, anyway,
most computers processors are x86.
Good luck.
↑ ↓ ← → Dennis Kempin <dennis xardias.net> writes:
Heinz wrote:
You could insert a block of asm code. Look here
http://www.digitalmars.com/d/iasm.html for valid opcodes. Here
http://www.acm.uiuc.edu/sigmil/talks/shellcode/sleep.asm is an approach.
This method is platform independant but not architecture independant,
anyway, most computers processors are x86.
Good luck.
Hi Heinz,
thanks for your reply. I tried the following solution:
int timerFunction()
{
while(true)
{
writefln("a");
asm
{
xor EAX,EAX;
mov EBX,0x77e61bea;
mov AX,1000;
push EAX;
call EBX;
}
}
return 0;
}
but the result is a crash without any error message or warning. As the
comment of the asm code says "windows shellcode" i think it simply uses the
windows internel Sleep method. Still no way to make the thread go sleep in
linux.
Maybe I just should use linux/windows c API methods and insert a platform
fork. I will report here if i got a working solution.. Maybe I am not the
only one who needs timing.
regards
Dennis
↑ ↓ ← → Bill Baxter <dnewsgroup billbaxter.com> writes:
Dennis Kempin wrote:
...
Maybe I just should use linux/windows c API methods and insert a platform
fork. I will report here if i got a working solution.. Maybe I am not the
only one who needs timing.
No, I suspect you're probably not the only one. Seems like most Thread
apis I've seen have had some sort of Sleep() method. Not sure why
Phobos' doesn't. Hopefully Tango will have a sleep().
--bb
↑ ↓ ← → Don Clugston <dac nospam.com.au> writes:
Bill Baxter wrote:
Dennis Kempin wrote:
> ...
Maybe I just should use linux/windows c API methods and insert a platform
fork. I will report here if i got a working solution.. Maybe I am not the
only one who needs timing.
No, I suspect you're probably not the only one. Seems like most Thread
apis I've seen have had some sort of Sleep() method. Not sure why
Phobos' doesn't.
Hopefully Tango will have a sleep().
It does.
--bb
↑ ↓ ← → Dennis Kempin <dennis xardias.net> writes:
okay here we go, i have a simple conditional compilation added to use
windows Sleep or linux usleep function.
Maybe someone has use for this simple class. You can decide if the timed
event shall be called once or forever until the process/thread is
terminated.
I have not tested this in windows but it "should" work ;)
regards Dennis
import std.thread;
version(Windows)
{
extern (C)
{
void Sleep(int);
}
}
version(linux)
{
extern (C)
{
void usleep(int);
}
}
class Timer: Thread
{
private void delegate() action;
private int waitTime;
private bit autoRestart;
this(int waitTime, void delegate() action, bit autoRestart=false)
{
this.action = action;
this.waitTime = waitTime;
this.autoRestart = autoRestart;
}
protected this(int waitTime, bit autoRestart=false)
{
this.waitTime = waitTime;
this.autoRestart = autoRestart;
}
override int run()
{
sleep(waitTime);
execute();
while(autoRestart)
{
sleep(waitTime);
execute();
}
return 0;
}
void execute()
{
action();
}
private void sleep(int time)
{
version(Windows)
{
Sleep(time);
}
version(linux)
{
usleep(time*1000);
}
}
}
↑ ↓ ← → BCS <BCS pathlink.com> writes:
Dennis Kempin wrote:
Hi,
i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):
class Timer: Thread
{
int run()
{
while(true)
{
this.wait(1000); // wait one second
writefln("one second passed");
}
return 0;
}
}
But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).
regards
Dennis
I'd try something with Thread.yield and a time check.
Example (insert your favorite time API)
class Timer : Thread
{
run()
{
auto next = CurrentTime()+inc;
while(running)
{
auto now = CurrentTime();
if(now > next)
{
dg();
next += inc;
}
else
this.yield();
}
}
}
↑ ↓ ← → Max Samukha <samukha voliacable.com> writes:
On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS pathlink.com> wrote:
Dennis Kempin wrote:
Hi,
i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):
class Timer: Thread
{
int run()
{
while(true)
{
this.wait(1000); // wait one second
writefln("one second passed");
}
return 0;
}
}
But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).
regards
Dennis
I'd try something with Thread.yield and a time check.
Example (insert your favorite time API)
class Timer : Thread
{
run()
{
auto next = CurrentTime()+inc;
while(running)
{
auto now = CurrentTime();
if(now > next)
{
dg();
next += inc;
}
else
this.yield();
}
}
}
Be careful about Thread.yield under Windows. It calls Sleep(0) that
won't yield to a thread of a lower priority. In case of the proposed
timer this is not a problem except it will use 100% of CPU and won't
let any lower priority thread run but if you use something like a spin
lock waiting for a lower priority thread to release it, the lock will
never be released. You could use Sleep(1) or SwitchToThread() on
single processor systems. And you should use 'rep nop' for
hyperthreaded CPUs.
A platform independent way to put a thread to sleep using Phobos:
import std.c.time;
sleep(1);// secs
msleep(1000); millisecs
http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
↑ ↓ ← → BCS <BCS pathlink.com> writes:
Max Samukha wrote:
On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS pathlink.com> wrote:
Dennis Kempin wrote:
Hi,
i just started to learn D (have been using c++ or java up to now) and am
wondering how to implement some kind of timer, a thread that calls a
delegate every n seconds.
This was my first idea (without flags for stopping the timer etc):
class Timer: Thread
{
int run()
{
while(true)
{
this.wait(1000); // wait one second
writefln("one second passed");
}
return 0;
}
}
But writefln never gets executed, because this.wait is used to wait for
other threads than the current one. Is there any other way to get let
Thread sleep for some seconds (I know that there is a Sleep function for
Win32, but a platform independend way would be very great).
regards
Dennis
I'd try something with Thread.yield and a time check.
Example (insert your favorite time API)
class Timer : Thread
{
run()
{
auto next = CurrentTime()+inc;
while(running)
{
auto now = CurrentTime();
if(now > next)
{
dg();
next += inc;
}
else
this.yield();
}
}
}
Be careful about Thread.yield under Windows. It calls Sleep(0) that
won't yield to a thread of a lower priority. In case of the proposed
timer this is not a problem except it will use 100% of CPU and won't
let any lower priority thread run but if you use something like a spin
lock waiting for a lower priority thread to release it, the lock will
never be released.
Ouch, I hadn't head of that.
You could use Sleep(1) or SwitchToThread() on
single processor systems. And you should use 'rep nop' for
hyperthreaded CPUs.
A platform independent way to put a thread to sleep using Phobos:
import std.c.time;
sleep(1);// secs
msleep(1000); millisecs
http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
However that gives the problem of not accounting for the run time of the
threads "action". Not alwyas a problem, but...
What is thread suposed to do to "kill time"? e.i. let other things run
with out using up much CPU but keep poling the thread.
while(NothingToDo())
thisThread.MarkTime();
↑ ↓ ← → Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
BCS wrote:
Max Samukha wrote:
A platform independent way to put a thread to sleep using Phobos:
import std.c.time;
sleep(1);// secs
msleep(1000); millisecs
http://www.digitalmars.com/d/archives/digitalmars/D/29144.html
However that gives the problem of not accounting for the run time of the
threads "action". Not alwyas a problem, but...
What is thread suposed to do to "kill time"? e.i. let other things run
with out using up much CPU but keep poling the thread.
while(NothingToDo())
thisThread.MarkTime();
Couldn't you just do something like:
-----
time_t nextEvent = currentTime() + interval;
time_t now;
while (true) {
while ((now = currentTime()) < nextEvent)
sleep(nextEvent - now); // or msleep, if you prefer
nextEvent += interval;
action();
}
-----
(where time_t is some type suitable for measuring time)
That should sleep until it's time, right?
↑ ↓ ← → BCS <ao pathlink.com> writes:
Reply to Frits,
BCS wrote:
while(NothingToDo())
thisThread.MarkTime();
Couldn't you just do something like:
-----
time_t nextEvent = currentTime() + interval;
time_t now;
while (true) {
while ((now = currentTime()) < nextEvent)
sleep(nextEvent - now); // or msleep, if you prefer
nextEvent += interval;
action();
}
-----
(where time_t is some type suitable for measuring time)
That should sleep until it's time, right?
That would work if the end condition is a clock time. It's not quite the
same problem but what about if you are waiting for some logical condition?
↑ ↓ ← → Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
BCS wrote:
Reply to Frits,
BCS wrote:
while(NothingToDo())
thisThread.MarkTime();
Couldn't you just do something like:
-----
time_t nextEvent = currentTime() + interval;
time_t now;
while (true) {
while ((now = currentTime()) < nextEvent)
sleep(nextEvent - now); // or msleep, if you prefer
nextEvent += interval;
action();
}
-----
(where time_t is some type suitable for measuring time)
That should sleep until it's time, right?
That would work if the end condition is a clock time. It's not quite the
same problem but what about if you are waiting for some logical condition?
Then you pick a reasonable poll interval and do something like this:
---
time_t nextCheck = currentTime();
while(true) {
while (!condition()) {
nextCheck += poll_interval;
sleep(nextCheck - currentTime());
}
action();
}
---
↑ ↓ ← → BCS <ao pathlink.com> writes:
Reply to Frits,
Then you pick a reasonable poll interval and do something like this:
Man, wouldn't it be better if the OS writers would just put in a proper yield?
|