在Python中与无限循环一起运行服务器 [英] Run server alongside infinite loop in Python

查看:82
本文介绍了在Python中与无限循环一起运行服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

#!/usr/bin/python
import StringIO
import subprocess
import os
import time
from datetime import datetime
from PIL import Image

# Original code written by brainflakes and modified to exit
# image scanning for loop as soon as the sensitivity value is exceeded.
# this can speed taking of larger photo if motion detected early in scan

# Motion detection settings:
# need future changes to read values dynamically via command line parameter or xml file
# --------------------------
# Threshold      - (how much a pixel has to change by to be marked as "changed")
# Sensitivity    - (how many changed pixels before capturing an image) needs to be higher if noisy view
# ForceCapture   - (whether to force an image to be captured every forceCaptureTime seconds)
# filepath       - location of folder to save photos
# filenamePrefix - string that prefixes the file name for easier identification of files.
threshold = 10
sensitivity = 180
forceCapture = True
forceCaptureTime = 60 * 60 # Once an hour
filepath = "/home/pi/camera"
filenamePrefix = "capture"
# File photo size settings
saveWidth = 1280
saveHeight = 960
diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on disk

# Capture a small test image (for motion detection)
def captureTestImage():
    command = "raspistill -w %s -h %s -t 500 -e bmp -o -" % (100, 75)
    imageData = StringIO.StringIO()
    imageData.write(subprocess.check_output(command, shell=True))
    imageData.seek(0)
    im = Image.open(imageData)
    buffer = im.load()
    imageData.close()
    return im, buffer

# Save a full size image to disk
def saveImage(width, height, diskSpaceToReserve):
    keepDiskSpaceFree(diskSpaceToReserve)
    time = datetime.now()
    filename = filepath + "/" + filenamePrefix + "-%04d%02d%02d-%02d%02d%02d.jpg" % ( time.year, time.month, time.day, time.hour, time.minute, time.second)
    subprocess.call("raspistill -w 1296 -h 972 -t 1000 -e jpg -q 15 -o %s" % filename, shell=True)
    print "Captured %s" % filename

# Keep free space above given level
def keepDiskSpaceFree(bytesToReserve):
    if (getFreeSpace() < bytesToReserve):
        for filename in sorted(os.listdir(filepath + "/")):
            if filename.startswith(filenamePrefix) and filename.endswith(".jpg"):
                os.remove(filepath + "/" + filename)
                print "Deleted %s to avoid filling disk" % filename
                if (getFreeSpace() > bytesToReserve):
                    return

# Get available disk space
def getFreeSpace():
    st = os.statvfs(".")
    du = st.f_bavail * st.f_frsize
    return du

# Get first image
image1, buffer1 = captureTestImage()

# Reset last capture time
lastCapture = time.time()

# added this to give visual feedback of camera motion capture activity.  Can be removed as required
os.system('clear')
print "            Motion Detection Started"
print "            ------------------------"
print "Pixel Threshold (How much)   = " + str(threshold)
print "Sensitivity (changed Pixels) = " + str(sensitivity)
print "File Path for Image Save     = " + filepath
print "---------- Motion Capture File Activity --------------"

while (True):

    # Get comparison image
    image2, buffer2 = captureTestImage()

    # Count changed pixels
    changedPixels = 0
    for x in xrange(0, 100):
        # Scan one line of image then check sensitivity for movement
        for y in xrange(0, 75):
            # Just check green channel as it's the highest quality channel
            pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])
            if pixdiff > threshold:
                changedPixels += 1

        # Changed logic - If movement sensitivity exceeded then
        # Save image and Exit before full image scan complete
        if changedPixels > sensitivity:   
            lastCapture = time.time()
            saveImage(saveWidth, saveHeight, diskSpaceToReserve)
            break
        continue

    # Check force capture
    if forceCapture:
        if time.time() - lastCapture > forceCaptureTime:
            changedPixels = sensitivity + 1

    # Swap comparison buffers
    image1  = image2
    buffer1 = buffer2

此代码会在检测到运动后拍摄照片,并且一直保持这种状态,直到我手动将其停止为止. (我应该提到该代码是用于Raspberry Pi计算机的)

This code takes a picture once movement is detected, and keeps doing so until I manually stop it. (I should mention that the code is for use with the Raspberry Pi computer)

在Stackoverflow上,我还有Nathan Jhaveri的以下代码:

I also have the following code courtesy of Nathan Jhaveri here on Stackoverflow:

import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler

def some_function():
    print "some_function got called"

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/captureImage':
            saveImage(saveWidth, saveHeight, diskSpaceToReserve)

        self.send_response(200)

httpd = SocketServer.TCPServer(("", 8080), MyHandler)
httpd.serve_forever()

此代码运行一个简单的服务器,该服务器将执行

This code runs a simple server that would execute the

saveImage(saveWidth, saveHeight, diskSpaceToReserve)

在服务器上访问url/captureImage时起作用.但是我遇到了一个问题.由于这两段代码都是无限循环,因此它们不能并行运行.我以为我需要做某种多线程,但这是我以前从未在Python中尝试过的东西.如果有人可以帮助我重回正轨,我将不胜感激.

function when the url /captureImage is visited on the server. I have run into a problem with this though. Since the two pieces of code are both infinite loops, they cannot run side by side. I would assume I need to do some kind of multi-threading, but that is something I have never experimented with in Python before. I would appreciate if anyone could help me get back on track with this.

推荐答案

尝试获取Web服务器,并在后台线程上运行它,以便调用"serve_forever()"不会阻止主线程的"while True:"循环.将现有对httpd.serve_forever()的调用替换为以下内容:

Try taking the webserver, and running it on a background thread so that calling "serve_forever()" does not block the main thread's "while True:" loop. Replace the existing call to httpd.serve_forever() with something like:

import threading
class WebThread(threading.Thread):
    def run(self):
        httpd = SocketServer.TCPServer(("", 8080), MyHandler)
        httpd.serve_forever()

WebThread().start()

确保代码块在"while(True):"循环之前运行,并且应该同时运行webserver循环和主线程循环.

Make sure that chunk of code runs before the "while (True):" loop, and you should have both the webserver loop and the main thread loop running.

请记住,拥有多个线程会变得很复杂.当两个线程同时访问同一资源时会发生什么?正如Velox在另一个答案中提到的那样,值得更多地了解线程.

Keep in mind that having multiple threads can get complicated. What happens when two threads access the same resource at the same time? As Velox mentioned in another answer, it is worthwhile to learn more about threading.

这篇关于在Python中与无限循环一起运行服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆