0

I've got this program:

import multiprocessing
import time

def timer(sleepTime):
    time.sleep(sleepTime)
    fooProcess.terminate()
    fooProcess.join() #line said to "cleanup", not sure if it is required, refer to goo.gl/Qes6KX

def foo():
    i=0
    while 1 
        print i
        time.sleep(1)
        i
        if i==4:
            #pause timerProcess for X seconds

fooProcess = multiprocessing.Process(target=foo, name="Foo", args=())
timer()
fooProcess.start()

And as you can see in the comment, under certain conditions (in this example i has to be 4) the timer has to stop for a certain X time, while foo() keeps working. Now, how do I implement this?

N.B.: this code is just an example, the point is that I want to pause a process under certain conditions for a certain amount of time.

Mat
  • 202,337
  • 40
  • 393
  • 406
gabmus
  • 53
  • 6
  • 2
    Can you tell us at a higher level what you're trying to accomplish? That is, *why* do you need this timer, and what exactly drives the semantics you're going for here? – John Zwinck May 25 '14 at 13:46
  • It's pretty simple, I'm writing a program (actually is a CLI minigame for a project I'm working on) which under certain conditions triggers a timer. While this timer is active the program has to be running normally, but when the time runs out, the whole program has to stop. By activating a specific function, the timer has to paused for X seconds. This could also be accomplished by extending the timer's time, but I think this bay be even trickier. – gabmus May 25 '14 at 14:51

4 Answers4

0

roughly:

  1. get the current timestamp at the time start time (time.time(), I presume)
  2. sleep with Event.wait(timeout=...)
  3. wake up on an Event or timeout.
  4. if on Event: get timestamp, subtract initial on, subtract result from timer; wait until foo() stops; repeat Event.wait(timeout=[result from 4.])
  5. if on timeout: exit.
svinota
  • 779
  • 8
  • 10
0

Here is an example, how I understand, what your Programm should do:

import threading, time, datetime

ACTIVE = True

def main():
    while ACTIVE:
        print "im working"
        time.sleep(.3)

def run(thread, timeout):
    global ACTIVE
    thread.start()
    time.sleep(timeout)
    ACTIVE = False

    thread.join()


proc = threading.Thread(target = main)

print datetime.datetime.now()
run(proc, 2)  # run for 2 seconds
print datetime.datetime.now()

In main() it does a periodic task, here printing something. In the run() method you can say, how long main should do the task.

This code producess following output:

2014-05-25 17:10:54.390000
im working
im working
im working
im working
im working
im working
im working
2014-05-25 17:10:56.495000

please correct me, if I've understood you wrong.

DiKorsch
  • 1,240
  • 9
  • 20
0

I would use multiprocessing.Pipe for signaling, combined with select for timing:

#!/usr/bin/env python

import multiprocessing
import select
import time

def timer(sleeptime,pipe):
    start = time.time()
    while time.time() < start + sleeptime:
        n = select.select([pipe],[],[],1) # sleep in 1s intervals
        for conn in n[0]:
            val = conn.recv()
            print 'got',val
            start += float(val)

def foo(pipe):
    i = 0
    while True:
        print i
        i += 1
        time.sleep(1)
        if i%7 == 0:
            pipe.send(5)

if __name__ == '__main__':
    mainpipe,foopipe = multiprocessing.Pipe()
    fooProcess = multiprocessing.Process(target=foo,name="Foo",args=(foopipe,))
    fooProcess.start()
    timer(10,mainpipe)
    fooProcess.terminate()
    # since we terminated, mainpipe and foopipe are corrupt
    del mainpipe, foopipe
    # ...
    print 'Done'

I'm assuming that you want some condition in the foo process to extend the timer. In the sample I have set up, every time foo hits a multiple of 7 it extends the timer by 5 seconds while the timer initially counts down 10 seconds. At the end of the timer we terminate the process - foo won't finish nicely at all, and the pipes will get corrupted, but you can be certain that it'll die. Otherwise you can send a signal back along mainpipe that foo can listen for and exit nicely while you join.

Mostly Harmless
  • 887
  • 1
  • 9
  • 9
  • Thank you, this should work! Just give me the time to get confident with your code and implement it into mine. – gabmus May 25 '14 at 15:42
0

I am think you're going about this wrong for game design. Games always (no exceptions come to mind) use a primary event loop controlled in software.

Each time through the loop you check the time and fire off all the necessary events based on how much time has elapsed. At the end of the loop you sleep only as long as necessary before you got the next timer or event or refresh or ai check or other state change.

This gives you the best performance regarding lag, consistency, predictability, and other timing features that matter in games.

tylerl
  • 30,197
  • 13
  • 80
  • 113