如何在脚本中停止脚本

时间:2018-01-19 09:41:10

标签: python kill terminate

我希望使用X-CTU通过Zigbee / XBee控制脚本。我创建了一个名为zb_control.py的脚本。现在我正在尝试启动并停止此脚本中的另一个脚本。脚本adxl345test.py用于从我的Raspberry Pi上附加的加速度计收集数据。

zb_control.py脚本背后的想法是我运行它然后如果我在X-CTU中输入“run”,脚本将开始运行adxl345test.py并收集数据。

我正在尝试在脚本中创建一个脚本,该脚本也可以再次停止,然后仍然准备好zb_control.py来接收来自X-CTU的新输入。

正如你所知,我尝试了不同的东西:

import serial, time, sys, os, subprocess
from subprocess import check_call
from subprocess import call

while True:

    ser=serial.Serial('/dev/ttyUSB0',9600,timeout=2)
    inc=ser.readline().strip()

    if inc=='run':
        print("---------------")
        print("Collecting data")
        print("---------------")
        p = subprocess.Popen("/home/pi/adxl345test.py", stdout=subprocess.PIPE, shell=True)

    elif inc=='stop':
        # check_call(["pkill", "-9", "-f", adxl345test.py])
        # serial.write('\x03')
        # os.system("pkill –f adxl345test.py")
        # call(["killall", "adxl345test.py"])
        p.kill()
        print("-----------------------")
        print("Script has been stopped")
        print("-----------------------")

我让它运行,它现在正在收集数据。但是现在问题是再次停止adxl345test.py。从上面的脚本可以看出我正在使用p.kill(),但脚本不会停止收集数据。当我在XCTU中输入“stop”时,我的zb_control.py会打印print-commands,但p.kill()没有被执行。有什么建议吗?

我已尝试单独使用p.terminate()并与p.kill()一起使用命令,但它不会停止adxl345test.py脚本。我可以说.csv文件的大小仍然在增加,因此脚本仍然必须收集数据。

2 个答案:

答案 0 :(得分:0)

以下是感兴趣的人的adxl345test.py脚本:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Example on how to read the ADXL345 accelerometer.
# Kim H. Rasmussen, 2014
import sys, math, os, spidev, datetime, ftplib

# Setup SPI
spi = spidev.SpiDev()
#spi.mode = 3    <-- Important: Do not do this! Or SPI won't work as intended, or even at all.
spi.open(0,0)
spi.mode = 3

# Read the Device ID (should be xe5)
id = spi.xfer2([128,0])
print 'Device ID (Should be 0xe5):\n'+str(hex(id[1])) + '\n'

# Read the offsets
xoffset = spi.xfer2([30 | 128,0])
yoffset = spi.xfer2([31 | 128,0])
zoffset = spi.xfer2([32 | 128,0])
accres = 2
accrate = 13
print 'Offsets: '
print xoffset[1]
print yoffset[1]
# print str(zoffset[1]) + "\n\nRead the ADXL345 every half second:"

# Initialize the ADXL345
def initadxl345():
    # Enter power saving state
    spi.xfer2([45, 0])
    # Set data rate to 100 Hz. 15=3200, 14=1600, 13=800, 12=400, 11=200, 10=100 etc.
    spi.xfer2([44, accrate])

    # Enable full range (10 bits resolution) and +/- 16g 4 LSB
    spi.xfer2([49, accres])

    # Enable measurement
    spi.xfer2([45, 8])

# Read the ADXL x-y-z axia
def readadxl345():
    rx = spi.xfer2([242,0,0,0,0,0,0])

    #
    out = [rx[1] | (rx[2] << 8),rx[3] | (rx[4] << 8),rx[5] | (rx[6] << 8)]
    # Format x-axis
    if (out[0] & (1<<16 - 1 )):
        out[0] = out[0] - (1<<16)
#   out[0] = out[0] * 0.004 * 9.82
    # Format y-axis
    if (out[1] & (1<<16 - 1 )):
        out[1] = out[1] - (1<<16)
#   out[1] = out[1] * 0.004 * 9.82
    # Format z-axis
    if (out[2] & (1<<16 - 1 )):
        out[2] = out[2] - (1<<16)
#   out[2] = out[2] * 0.004 * 9.82

    return out

# Initialize the ADXL345 accelerometer
initadxl345()

# Read the ADXL345 every half second
timetosend = 60
while(1):
    with open('/proc/uptime','r') as f: # get uptime
        uptime_start = float(f.readline().split()[0])
    uptime_last = uptime_start
    active_file_first = "S3-" + str(pow(2,accrate)*25/256) + "hz10bit" + str(accres) + 'g' + str(datetime.datetime.utcnow().strftime('%y%m%d%H%M')) $
    active_file = active_file_first.replace(":", ".")
    wStream = open('/var/log/sensor/' + active_file,'wb')
    finalcount = 0
    print "Creating " + active_file
    while uptime_last < uptime_start + timetosend:
        finalcount += 1
        time1 = str(datetime.datetime.now().strftime('%S.%f'))
        time2 = str(datetime.datetime.now().strftime('%M'))
        time3 = str(datetime.datetime.now().strftime('%H'))
        time4 = str(datetime.datetime.now().strftime('%d'))
        time5 = str(datetime.datetime.now().strftime('%m'))
        time6 = str(datetime.datetime.now().strftime('%Y'))
        axia = readadxl345()
        wStream.write(str(round(float(axia[0])/1024,3))+','+str(round(float(axia[1])/1024,3))+','+str(round(float(axia[2])/1024,3))+','+time1+','+ti$
    # Print the reading
    # print axia[0]
    # print axia[1]
    # print str(axia[2]) + '\n'
    # elapsed = time.clock()
    # current = 0
    # while(current < timeout):
    #   current = time.clock() - elapsed
        with open('/proc/uptime', 'r') as f:
                uptime_last = float(f.readline().split()[0])
    wStream.close()

def doftp(the_active_file):
    session = ftplib.FTP('192.0.3.6','sensor3','L!ghtSp33d')
    session.cwd("//datalogger//")
    file = open('/var/log/sensor/' + active_file, 'rb')   # file to send
    session.storbinary('STOR' + active_file, file)        # send the file
    file.close()
    session.quit

答案 1 :(得分:0)

我的建议:

  • 如果你在指定的时间间隔内做某事,你可能最好使用threading.Timer,而不是自己检查时间。
  • 正如我在评论中所说,您可以检查退出条件,而不是残酷地杀死该过程。这也可以正确地清理你需要的东西。
  • 那些time1...time6真的不好看,列表怎么样?此外,未使用time2, time3, time4, time5, time6
  • 你实际上并不需要strftime来获取时间,日,月,年等等。他们已经作为属性存在。

您可以执行以下操作:

cur_time = datetime.datetime.now()
cur_hour = cur_time.hour
cur_minute = cur_time.minute

......等等,哪个更好一点。在这种特殊情况下,它不重要,但是如果你开始测量毫秒,那么在几行代码之后时间会略有不同,所以你应该存储它并从变量中使用它。

至于其余部分,如果你想要一个例子,我在这里检查一个文件是否存在以确定是否停止。它非常粗糙,但应该给你一个起点:

from threading import *
from os.path import exists

def hello():
    print('TEST') # Instead of this, do what you need
    if (exists('stop_file.txt')):
        return
    t = Timer(0.5, hello)
    t.start()

hello()

然后在另一个创建中,您希望它停止时创建停止文件(在再次启动之前不要忘记添加一行以将其删除)。