初始化数组时出现分段错误
Segmentation fault when initializing array
我在初始化数组时遇到分段错误。
我有一个 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"])
行而发生错误。我知道,因为当我用打印调用替换它时,程序将 运行 就好了。我尝试过对数组对象(整数)使用不同类型,在附加函数之外创建相同对象的数组等。出于某种原因,仅在 "readTag" 函数内创建数组会导致分段错误,例如row = [1,2,3]
有谁知道导致此错误的原因以及如何修复它?另外更具体一点,readTag 函数在前两次(只有两次)调用中可以正常工作,但随后它崩溃并且具有 start_reading() 函数的 Reader 对象是来自 mercury-api
我觉得这像是一个范围界定问题; mercury 库无权访问您的列表的内存地址,因此当它调用您的回调函数时 readTag(e)
会发生段错误。我认为该库不支持您想要的行为
为了扩展 Michael 的回答,这似乎是范围界定和您正在使用的 API 的问题。一般来说,pure-Python 不会出现段错误。或者至少,它 不应该 段错误,除非解释器或您正在使用的某些扩展中存在错误。这并不是说 pure-Python 不会崩溃,只是真正的段错误表明问题可能是您的代码之外的一些混乱的结果。
我假设您正在使用 this Python API。
在这种情况下,README.md 提到您使用的 Reader.start_reader()
方法是 "asynchronous"。这意味着它会立即调用一个新线程或进程 returns,然后后台线程会在每次扫描某些内容时继续调用您的回调。
我不太了解 CPython 的细节,无法准确说明发生了什么,但您已将 IDS = []
声明为全局变量,这似乎是背景线程是 运行 与主程序具有不同上下文的回调。因此,当它尝试访问 IDS
时,它正在读取它不拥有的内存,因此出现段错误。
由于回调的限制程度以及明显缺乏缓冲区,这可能是代表开发人员的疏忽。如果您确实需要异步读取,则值得向他们发送问题报告。
否则,考虑到您只是在等待输入,您可能不需要异步读取,您可以在自己的繁忙循环中使用同步 Reader.read()
方法,而不是像这样:
try:
while True:
readTags(r.read(timeout=10))
except KeyboardInterrupt: ## break loop on SIGINT (Ctrl-C)
pass
请注意 r.read()
returns 标签列表而不是一个标签,因此您需要稍微修改您的回调,如果您编写的不仅仅是一个快速脚本,您可能想使用线程来正确地中断循环,因为 SIGINT 非常笨拙。
我在初始化数组时遇到分段错误。
我有一个 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"])
行而发生错误。我知道,因为当我用打印调用替换它时,程序将 运行 就好了。我尝试过对数组对象(整数)使用不同类型,在附加函数之外创建相同对象的数组等。出于某种原因,仅在 "readTag" 函数内创建数组会导致分段错误,例如row = [1,2,3]
有谁知道导致此错误的原因以及如何修复它?另外更具体一点,readTag 函数在前两次(只有两次)调用中可以正常工作,但随后它崩溃并且具有 start_reading() 函数的 Reader 对象是来自 mercury-api
我觉得这像是一个范围界定问题; mercury 库无权访问您的列表的内存地址,因此当它调用您的回调函数时 readTag(e)
会发生段错误。我认为该库不支持您想要的行为
为了扩展 Michael 的回答,这似乎是范围界定和您正在使用的 API 的问题。一般来说,pure-Python 不会出现段错误。或者至少,它 不应该 段错误,除非解释器或您正在使用的某些扩展中存在错误。这并不是说 pure-Python 不会崩溃,只是真正的段错误表明问题可能是您的代码之外的一些混乱的结果。
我假设您正在使用 this Python API。
在这种情况下,README.md 提到您使用的 Reader.start_reader()
方法是 "asynchronous"。这意味着它会立即调用一个新线程或进程 returns,然后后台线程会在每次扫描某些内容时继续调用您的回调。
我不太了解 CPython 的细节,无法准确说明发生了什么,但您已将 IDS = []
声明为全局变量,这似乎是背景线程是 运行 与主程序具有不同上下文的回调。因此,当它尝试访问 IDS
时,它正在读取它不拥有的内存,因此出现段错误。
由于回调的限制程度以及明显缺乏缓冲区,这可能是代表开发人员的疏忽。如果您确实需要异步读取,则值得向他们发送问题报告。
否则,考虑到您只是在等待输入,您可能不需要异步读取,您可以在自己的繁忙循环中使用同步 Reader.read()
方法,而不是像这样:
try:
while True:
readTags(r.read(timeout=10))
except KeyboardInterrupt: ## break loop on SIGINT (Ctrl-C)
pass
请注意 r.read()
returns 标签列表而不是一个标签,因此您需要稍微修改您的回调,如果您编写的不仅仅是一个快速脚本,您可能想使用线程来正确地中断循环,因为 SIGINT 非常笨拙。