初始化数组时出现分段错误

时间:2018-11-01 21:09:37

标签: python segmentation-fault rfid

初始化数组时出现分段错误。

从读取RFID标签起,我就具有回调功能

IDS = []
def readTag(e):
    epc = str(e.epc, 'utf-8')
    if not epc in IDS:
        now = datetime.datetime.now().strftime('%m/%d/%Y %H:%M:%S')
        IDS.append([epc, now, "name.instrument"])

以及从中调用的主要功能

def main():
    for x in vals:
        IDS.append([vals[0], vals[1], vals[2]])
    for x in IDS:
        print(x[0])
    r = mercury.Reader("tmr:///dev/ttyUSB0", baudrate=9600)
    r.set_region("NA")

    r.start_reading(readTag, on_time=1500)
    input("press any key to stop reading: ")
    r.stop_reading()

由于行IDS.append([epc, now, "name.instrument"])而发生错误。我知道,因为当我用打印调用替换它时,程序将运行正常。我尝试对数组对象(整数)使用不同类型,在append函数之外创建相同对象的数组,等等。由于某些原因,仅在“ readTag”函数内部创建数组会导致分段错误,例如{{ 1}}

有人知道导致此错误的原因以及如何解决该错误吗?同样,为了更具体一点,readTag函数对于前两个(只有两个)调用可以正常工作,但是随后崩溃,并且具有start_reading()函数的Reader对象来自mercury-api

2 个答案:

答案 0 :(得分:2)

对我来说,这似乎是一个范围界定问题;汞库没有访问列表的内存地址的权限,因此,当它调用回调函数readTag(e)时,会发生段错误。我认为该库不支持您想要的行为

答案 1 :(得分:1)

要扩展Michael的答案,这似乎是范围和您使用的API的问题。通常,纯Python不会出现段错误。至少,除非解释器中有错误或您使用的某些扩展名,否则它应该 段错误。这并不是说纯Python不会崩溃,而仅仅是一个真正的段错误指示问题可能是代码外杂乱的结果。

我假设您正在使用this Python API

在那种情况下,README.md提到您使用的Reader.start_reader()方法是“异步的”。这意味着它将调用一个新线程或进程并立即返回,然后每次扫描某些内容时,后台线程将继续调用您的回调。

我对CPython的本质不甚了解,无法确切说明发生了什么,但是您已经将IDS = []声明为全局变量,并且似乎后台线程正在使用与主程序的上下文不同。因此,当它尝试访问IDS时,它并不拥有内存,因此存在段错误。

由于回调的严格性以及明显缺乏缓冲区,因此这可能代表开发人员。如果您确实需要异步读取,则值得向他们发送问题报告。

否则,考虑到您只是在等待输入,则可能不需要异步读取,并且可以在自己的繁忙循环中使用同步Reader.read()方法,而不是类似以下内容:

try:
    while True:
        readTags(r.read(timeout=10))
except KeyboardInterrupt: ## break loop on SIGINT (Ctrl-C)
    pass

请注意,r.read()返回的是一个标签列表,而不只是一个标签列表,因此您需要稍微修改一下回调,并且如果您编写的不仅仅是快速脚本,您可能希望使用线程来由于SIGINT非常hacky,因此可以正确地中断循环。