digitalmars.D.learn - Implementing a timer using threads
- Dennis Kempin (23/23) Jan 27 2007 Hi,
- Heinz (5/32) Jan 28 2007 You could insert a block of asm code. Look here http://www.digitalmars.c...
- Dennis Kempin (28/36) Jan 29 2007 Hi Heinz,
- Bill Baxter (5/9) Jan 29 2007 No, I suspect you're probably not the only one. Seems like most Thread
- Don Clugston (2/14) Jan 30 2007
- Dennis Kempin (66/66) Jan 29 2007 okay here we go, i have a simple conditional compilation added to use
- BCS (21/48) Jan 29 2007 I'd try something with Thread.yield and a time check.
- Max Samukha (15/63) Jan 30 2007 Be careful about Thread.yield under Windows. It calls Sleep(0) that
- BCS (8/83) Jan 30 2007 However that gives the problem of not accounting for the run time of the...
- Frits van Bommel (14/32) Jan 30 2007 Couldn't you just do something like:
- BCS (3/21) Jan 30 2007 That would work if the end condition is a clock time. It's not quite the...
- Frits van Bommel (12/36) Jan 30 2007 Then you pick a reasonable poll interval and do something like this:
- BCS (3/4) Jan 30 2007 [snip]
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
Jan 27 2007
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 DennisYou 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.
Jan 28 2007
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
Jan 29 2007
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
Jan 29 2007
Bill Baxter wrote:Dennis Kempin wrote: > ...It does.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
Jan 30 2007
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); } } }
Jan 29 2007
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 DennisI'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(); } } }
Jan 29 2007
On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS pathlink.com> wrote:Dennis Kempin wrote: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.htmlHi, 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 DennisI'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(); } } }
Jan 30 2007
Max Samukha wrote:On Mon, 29 Jan 2007 10:55:37 -0800, BCS <BCS pathlink.com> wrote:Ouch, I hadn't head of that.Dennis Kempin wrote: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.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 DennisI'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(); } } }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.htmlHowever 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();
Jan 30 2007
BCS wrote:Max Samukha wrote: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?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.htmlHowever 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();
Jan 30 2007
Reply to Frits,BCS wrote: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?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?
Jan 30 2007
BCS wrote:Reply to Frits,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 wrote: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?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?
Jan 30 2007
Reply to Frits,Then you pick a reasonable poll interval and do something like this:[snip] Man, wouldn't it be better if the OS writers would just put in a proper yield?
Jan 30 2007