Python Forum
Code issue with time remaining loop. Python3
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Code issue with time remaining loop. Python3
#1
So I have an issue. im running a timer to turn a gpio port on and need to return a time stamp over rs232. I have the rs232 outputting just fine in its own function but the issue I am facing is that I need to send a cancel signal but it doesnt cancel the process. I'm using queue to pass the command over. its in python3. I'd greatly appreciate everyones ideas and help on how to sort out this issue. Its been an ongoing issue. I have tried queue's, event but doesnt seem to be working for me. I have also tried ctr.terminate but it gives me the error Nonetype doesnt have method terminate. Id prefer to use standard libraries if possible but have no problem if a custom class is the best way of doing it. its in python3.4 on raspberry pi 


def cleancycle(clean,seconds):
   print('time Remaining: {}'.format(seconds))
   queue=Queue()
   ctr=multiprocessing.Process(target=timeremaining,args=(seconds,queue,))
   ctr.daemon=True
   flag=0
   t=Timer(0+seconds,cleanoff)
   global cleanstate
   if clean=='1':
       queue.put(0)
       ctr.start()
       sensor=W1ThermSensor(W1ThermSensor.THERM_SENSOR_MAX31850K, config.grillsensor)   
       temperature_in_celsius=sensor.get_temperature()
       lid=True
       if lid==True:
           print('GPIO output')
           state=1
           sensor=W1ThermSensor(W1ThermSensor.THERM_SENSOR_MAX31850K, config.grillsensor)   
           temperature_in_celsius=sensor.get_temperature()
           t.start()
       elif clean=='0' and state==1:
           queue.put('stop')
           if ctr.is_alive():
               print('I'm alive')
           t.cancel()
           state=0

def timeremaining(seconds,queue):
   while seconds!=0:
       try:
           msg=queue.get()
           print('Time Remaining message: {}'.format(msg))
       except multiprocessing.queues.Empty:
           pass
       finally:
           if msg=='stop':
               print('Real OG')
               break
           else:
               print('time remaining: {}'.format(seconds))
               output=bytes('!T/{}\r'.format(seconds),'ascii')
               rs232output(output)
               seconds-=5
               time.sleep(5)
Reply
#2
so I have an issue. my queue isn't passing my updated message. My expected behaviour is it stops print time remaining after approx 10seconds. the actual behaviour is it continues printing time remaining until it counts down to zero.

import time
import multiprocessing
import queue 

def cleancycle(seconds):
    msgqueue=queue.Queue()
    ctr=multiprocessing.Process(target=timeremaining,args=(seconds,msgqueue,))
    print('clean')
    print('Queue: {}'.format(queue))
    print('clean on')
    ctr.start()
    time.sleep(10)
    msgqueue.put('stop')
    
def timeremaining(seconds,msgqueue):
    print('Time: {}'.format(seconds))
    print('Queue: {}'.format(queue))
    while seconds != 0:
        print('time remaining: {}'.format(seconds))
        seconds-=1
        time.sleep(1)
        if msgqueue.full():
            msg=msgqueue.get(False)
        if msgqueue=='stop':
            print('Exit loop')
            break
def main():
    seconds=100
    while True:
        cleancycle(seconds)
        time.sleep(120)    
        
if __name__ == '__main__':
    main()    
Reply
#3
Double posting isn't needed. I've merged the threads together.

(May-03-2017, 07:59 PM)deboerdn2000 Wrote:         if msgqueue=='stop':
            print('Exit loop')
            break

If msgqueue is a Queue, then that should never run, as it'd never equal the string "stop".
Aside from that, I can't run your code, due to a pickle error with the queue (it works if I just don't pass that parameter, but then it doesn't do anything since the queue is just None). Might be an unrelated issue on my end, though, as I rarely use the multiprocessing module.
Reply
#4
thats interesting. i ran it on the raspberry pi with python 3.4 just fine but doesnt seem to run when i test it on windows. wonder if thats part of my issue. any idea's on how to fix that?
Reply
#5
Ok, so after googling, the multiprocessing module itself has a version of Queue which is safe for... multiprocessing. So I made a few minor changes to use that queue instead, and also to how you're checking if there's a message in the queue (better to ask forgiveness than permission):

import time
import multiprocessing
import queue

def cleancycle(seconds):
    msgqueue=multiprocessing.Queue()
    ctr=multiprocessing.Process(target=timeremaining,args=(seconds,msgqueue))
    print('clean')
    print('Queue: {}'.format(queue))
    print('clean on')
    ctr.start()
    time.sleep(10)
    msgqueue.put('stop')

def timeremaining(seconds=0,msgqueue=None):
    print('Time: {}'.format(seconds))
    print('Queue: {}'.format(queue))
    while seconds != 0:
        print('time remaining: {}'.format(seconds))
        seconds-=1
        time.sleep(1)
        try:
            msg=msgqueue.get(False)
            if msg=='stop':
                print('Exit loop')
                break
        except queue.Empty:
            pass
def main():
    seconds=100
    while True:
        cleancycle(seconds)
        time.sleep(120)

if __name__ == '__main__':
    main()
Reply
#6
it looks like that works fine. i extended the code into my main program but is giving me issues still.

import time
import multiprocessing
import queue
 
def cleancycle(clean,seconds):
    msgqueue=multiprocessing.Queue()
    ctr=multiprocessing.Process(target=timeremaining,args=(seconds,msgqueue))
    ctr.daemon=True
    if not ctr.is_alive:
        ctr.start()
    print('clean')
    print('Queue: {}'.format(msgqueue))
    if clean=='1':
        print('clean is one')
        pass
    else:
        msgqueue.put('stop')
        
def timeremaining(seconds=0,msgqueue=None):
    print('Time: {}'.format(seconds))
    print('Queue: {}'.format(queue))
    while seconds != 0:
        print('time remaining: {}'.format(seconds))
        seconds-=1
        time.sleep(1)
        try:
            msg=msgqueue.get(False)
            if msg=='stop':
                print('Exit loop')
                break
        except queue.Empty:
            pass
def main():
    i=0
    seconds=100
    cleancycle('1',seconds)
    for i in range(0,30):
        print (i)
        i+=1
        time.sleep(1)
    cleancycle('2',seconds)
        
        
 
if __name__ == '__main__':
    main()
the issue im now facing is that it doesnt print time remaining. if you have any ideas to maybe restructure the program instead of reprogramming stuff that would be fine too
Reply
#7
(May-03-2017, 11:00 PM)deboerdn2000 Wrote: ctr=multiprocessing.Process(target=timeremaining,args=(seconds,msgqueue))
ctr.daemon=True
if not ctr.is_alive:
ctr.start()

ctr.is_alive is a function. Functions are always truthy, you probably want to actually call the function :p

Or just remove the if statement, since it'd never be alive.
Reply
#8
well sorted that issue out. for some reason it works fine on python 3.4 on my raspberry pi but not 3.6 on windows 

pi2: '3.4.2 (default, Oct 19 2014, 13:31:11) \n[GCC 4.9.1]'
windows 7: '3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)]'

it solves my problem but im curious why it doesnt output on windows just fine but on my pi it does. 

pi output:

clean
Queue: <multiprocessing.queues.Queue object at 0x76a2f6d0>
clean is one
0
Time: 100
time remaining: 100
1
time remaining: 99
2
time remaining: 98
3
time remaining: 97
4
time remaining: 96
5
time remaining: 95
6
time remaining: 94
7
time remaining: 93
8
time remaining: 92
9
time remaining: 91
clean
Queue: <multiprocessing.queues.Queue object at 0x7686ce70>
time remaining: 90

windows just prints 0,1,2,3,4,5,6 and so on . 

is it perhaps version difference but you would think that the code would be cross platform.
Reply
#9
You only ever put "stop" in the queue the second time you call cleancycle, which means the first queue, from the first time you call it, never gets that message, so the first extra process you create never gets that message (but the second extra process would).

Maybe it works fine on the raspberry because maybe python on the raspberry doesn't actually support multiprocessing, and only fakes it. I don't think that's actually the case, since it's just debian, right? So it's not like it's a special version of python for the raspberry.
Reply
#10
import time
from multiprocessing import Queue, Process
from queue import Empty
 
def cleancycle(clean,seconds):
    msgqueue=Queue()
    ctr=Process(target=timeremaining,args=(seconds,msgqueue))
    ctr.daemon=True
    if not ctr.is_alive():
        ctr.start()
    print('\n Clean: {}'.format(clean))
    if clean=='1':
        pass
    else:
        msgqueue.put('stop')
        
def timeremaining(seconds=0,msgqueue=None):
    while seconds != 0:
        print('\n time remaining: {}'.format(seconds))
        seconds-=5
        time.sleep(5)
        try:
            msg=msgqueue.get(False)
            if msg=='stop':
                print('Exit loop')
                break
        except Empty:
            pass
def main():
    seconds=100
    while True:
        print('Enter 0 or 1')
        clean=input('Entry:')
        
        if clean=='1':
            cleancycle('1',seconds)
        elif clean=='0':
            cleancycle('0',0)
        print('\n next loop')
        time.sleep(1)
            
        
 
if __name__ == '__main__':
    main()
so my actual output is: 
Enter 0 or 1
Entry:1

 Clean: 1

 next loop

    time remaining: 100
Enter 0 or 1
Entry:
    time remaining: 95
0 # entry
    time remaining: 90


 Clean: 0

 next loop
Enter 0 or 1
Entry:

what i expect it to do though is go time remaining: 100, time remaining:95 and so on until 0 is entered at which it then stops. found out the idle has the issue but does fine with just running it normally in windows.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Updating Code And Having Issue With Keys Xileron 8 1,163 May-25-2023, 11:14 PM
Last Post: DigiGod
  Python3 for loop over a dict ogautier 3 1,387 Feb-25-2022, 10:17 AM
Last Post: Larz60+
  NameError issue with daughter's newb code MrGonk 2 1,451 Sep-16-2021, 01:29 PM
Last Post: BashBedlam
  Calculator code issue using list kirt6405 4 2,281 Jun-11-2021, 10:13 PM
Last Post: topfox
  How to measure execution time of a multithread loop spacedog 2 2,891 Apr-24-2021, 07:52 AM
Last Post: spacedog
  Assistance with running a few lines of code at an EXACT time nethatar 5 3,254 Feb-24-2021, 10:43 PM
Last Post: nilamo
  Stumped by my own code (ratio & epoch-time calculation). MvGulik 2 2,143 Dec-30-2020, 12:04 AM
Last Post: MvGulik
  Code taking too much time to process ErPipex 11 4,959 Nov-16-2020, 09:42 AM
Last Post: DeaD_EyE
  What is the run time complexity of this code and please explain? samlee916 2 2,304 Nov-06-2020, 02:37 PM
Last Post: deanhystad
  The count variable is giving me a hard time in this code D4isyy 2 1,975 Aug-09-2020, 10:32 PM
Last Post: bowlofred

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020