如何在python中运行两个while True语句?

如何在python中运行两个while True语句?,python,raspberry-pi,Python,Raspberry Pi,我正在尝试用Python为我的Raspberry Pi制作一个刷卡系统。我把程序分成两部分:一个门铃和一个刷卡记录系统。这两个程序各自工作,但如何将这两个程序合并到一个python文件中?我试过穿线,但似乎不起作用 以下是节目: 1.)门警报:如果门在一定时间内保持打开状态,led将闪烁,然后警报将响起 import time import RPi.GPIO as gpio led = 37 buzzer = 11 door = 16 gpio.setmode(gpio.BOARD) gpi

我正在尝试用Python为我的Raspberry Pi制作一个刷卡系统。我把程序分成两部分:一个门铃和一个刷卡记录系统。这两个程序各自工作,但如何将这两个程序合并到一个python文件中?我试过穿线,但似乎不起作用

以下是节目: 1.)门警报:如果门在一定时间内保持打开状态,led将闪烁,然后警报将响起

import time
import RPi.GPIO as gpio

led = 37
buzzer = 11
door = 16

gpio.setmode(gpio.BOARD)
gpio.setwarnings(False)
gpio.setup(buzzer, gpio.OUT)
gpio.setup(led, gpio.OUT)
gpio.setup(door, gpio.IN, pull_up_down=gpio.PUD_UP)


def blink(buzzer):
    gpio.output(buzzer, True)
    time.sleep(0.1)
    gpio.output(buzzer, False)
    time.sleep(0.1)
    return

def blink(led):
    gpio.output(led, True)
    time.sleep(1)
    gpio.output(led, False)
    time.sleep(1)
    return

while True:
    if gpio.input(door):
        time.sleep(3)
        for i in range(0,5):
                blink(led)
        for i in range (0,5):
                blink(buzzer)
    else:
        gpio.output(buzzer, False)

gpio.cleanup()      
2.)刷卡记录系统:当有人刷卡时,led闪烁并拍照

import datetime
import time
import os
import RPi.GPIO as gpio

led = 37
t = datetime.datetime.now()

gpio.setmode(gpio.BOARD)
gpio.setwarnings(False)
gpio.setup(led, gpio.OUT)

def blink(led):
    gpio.output(led, True)
    time.sleep(0.1)
    gpio.output(led, False)
    time.sleep(0.1)

while True:
    card = raw_input()
    f = open("Laptop Sign Out" + '.txt', 'a')
    f.write("OneCard Number: " + card[1:10] + " Time: " + t.strftime("%m-%d-%Y %H:%M:%S"))
    f.write('\n')
    f.write(';')
    f.write('\n')
    f.close()
    time.sleep(1)
    for i in range(0,3):
        blink(led)
    os.system('fswebcam ~/Desktop/Photos/%H%M%S.jpeg')
    time.sleep(3)

gpio.cleanup()
(更新)另外,下面是我在线程方面的尝试:

import time
import RPi.GPIO as gpio
import os
import datetime
from threading import Thread

led = 37
buzzer = 11
door = 16
t = datetime.datetime.now()

gpio.setmode(gpio.BOARD)
gpio.setwarnings(False)
gpio.setup(buzzer, gpio.OUT)
gpio.setup(led, gpio.OUT)
gpio.setup(door, gpio.IN, pull_up_down=gpio.PUD_UP)


def blink(buzzer):
    gpio.output(buzzer, True)
    time.sleep(0.1)
    gpio.output(buzzer, False)
    time.sleep(0.1)
    return

def blink(led):
    gpio.output(led, True)
    time.sleep(1)
    gpio.output(led, False)
    time.sleep(1)
    return

def doorsensor():
    while True:
        if gpio.input(door):
            time.sleep(3)
            for i in range(0,5):
                    blink(led)
            for i in range (0,5):
                    blink(buzzer)
        else:
            gpio.output(buzzer, False)

def cardreader():
    while True:
        card = raw_input()
        f = open("Laptop Sign Out" + '.txt', 'a')
        f.write("OneCard Number: " + card[1:10] + " Time: " + t.strftime("%m-%d-%Y %H:%M:%S"))
        f.write('\n')
        f.write(';')
        f.write('\n')
        f.close()
        time.sleep(1)
        for i in range(0,3):
            blink(led)
        os.system('fswebcam ~/Desktop/Photos/%H%M%S.jpeg')
        time.sleep(3)

f1 = Thread(target = doorsensor())
f2 = Thread(target = cardreader())

f2.start()
f1.start()


gpio.cleanup()   

如果您试图同时运行这两个程序,那么您必须使用线程或多处理,您说您已经尝试过了。如果您有,我们可以看看您的尝试,因为我们可能会帮助您解决您的问题

另一个问题是,所有方法都命名为Blink,这在Python中是不允许的,在Python中,所有方法都应该有不同的名称


编辑:对于线程,请确保键入
threading.Thread(target=target)
作为您的代码

我正在介绍一种无线程方法。 其思想是将
while
主体转换为
update
函数,并交替调用它们

首先,您的门环变为

def update_door():
    if gpio.input(door):
        time.sleep(3)
        for i in range(0,5):
                blink(led)
        for i in range (0,5):
                blink(buzzer)
    else:
        gpio.output(buzzer, False)
然后,您的刷卡记录系统变为

def update_card():
    card = raw_input()
    f = open("Laptop Sign Out" + '.txt', 'a')
    f.write("OneCard Number: " + card[1:10] + " Time: " + t.strftime("%m-%d-%Y %H:%M:%S"))
    f.write('\n')
    f.write(';')
    f.write('\n')
    f.close()
    time.sleep(1)
    for i in range(0,3):
        blink(led)
    os.system('fswebcam ~/Desktop/Photos/%H%M%S.jpeg')
    time.sleep(3)

最后,主循环变成:

while True:
    update_door()
    update_card()
但是出现了一个问题:
时间。
更新卡中的睡眠也会延迟
更新门。
在这里,您有三种解决方案:

1-如果
update\u door
延迟,则可以

嗯,好的

2-如果
update\u door
延迟,则不正常,但如果
update\u card
未延迟,则正常

然后只需删除时间。睡眠(3)

3-您需要
更新\u门
不被延迟,并且
更新\u卡
被延迟

然后,您可以使用
time
模块设置手动计时器

lastCardUpdate = time.time()
while True:
    update_door()
    now = time.time()
    if now - lastCardUpdate >= 3:
        update_card()
        lastCardUpdate = now

但是
update\u card
中的
raw\u input
是一种阻塞方法,等待用户输入。 如果您确实需要每三秒进行一次此用户输入,则不能使用此方法。 如果您可以将其移动到
while
之前,即移动到
更新卡
功能之外,则可以。
否则,您将确实需要使用线程。

无论出现任何其他错误,您都需要在线程启动后加入其中一个线程

f1 = Thread(target = doorsensor())
f2 = Thread(target = cardreader())

f2.start()
f1.start()

f1.join()
f1.join()
做什么

基本上,它告诉Python等待
f1
完成运行。 如果不这样做,程序将启动f1和f2,然后退出。
退出后,Python将释放所有资源,包括停止执行的两个线程。

您需要将线程函数作为
目标
参数传递,而不是它们的返回值:

import sleep

f1 = Thread(target=doorsensor) # Remove parentheses after doorsensor
f1.daemon = True
f1.start()
f2 = Thread(target=cardreader) # Remove parentheses after cardreader
f2.daemon = True
f2.start()

# Use a try block to catch Ctrl+C
try:
    # Use a while loop to keep the program from exiting and killing the threads
    while True:
        time.sleep(1.0)
except KeyboardInterrupt:
    pass

gpio.cleanup()
在每个线程上设置
守护进程
属性,以便程序在只剩下守护进程线程时退出:

线程可以标记为“守护线程”。此标志的意义在于,当只剩下守护进程线程时,整个Python程序将退出。初始值从创建线程继承。可以通过daemon属性设置该标志


请发布您尝试的线程代码您可以显示您的
threading
尝试吗?你想把两个程序放在一个文件中的原因是什么?如果我可以问你为什么你认为这两个程序不应该是两个不同的程序?为了这个项目,为了方便起见,我被要求将这两个程序合并成一个。然而,我已经在这个问题上纠缠了几天,我决定向互联网寻求帮助。你的程序一开始就会或多或少退出吗?我认为你需要
加入你的一个线程。完全可以使用相同的名称多次定义一个方法。每个
def
都将覆盖函数的上一个值。我已经发布了我的线程尝试。请让我知道您的想法@右腿抱歉,我以为您不能使用相同的名称。因为如果你想调用所有的方法,除非你在处理各种bloink函数和will
raw\u input
block?@doctorlove Oh之后使用本文中讨论的某些变通方法,否则不会有问题。当然会的。那么,就需要一根线了。我正在编辑我的答案。@Draenokh当然是因为
原始输入的缘故。
。如果更新门被延迟,这没关系。我试过你的密码。更新卡功能工作正常,但更新门功能不工作。知道为什么吗?在我的代码中没有任何错误的警告terminal@Draenokh正如我在上一段中所写,
raw\u input
是一个阻塞函数,因此我怀疑它会停止执行
update\u door
。由于这种阻塞方法,您确实需要使用多线程。检查我的另一个答案,我在其中解决了这个问题。我试过了,读卡器根本不工作。我怀疑可能是os.system调用弄乱了线程,但您是否知道读卡器为什么不能工作。结果表明,只有声明的第一个线程才能工作。假设首先声明了f2(f1=Thread(target=doorsensor()),那么只有f2会工作。下一个声明的线程不会工作。知道为什么吗?