【问题标题】:Python segmentation fault on Thread switch线程开关上的 Python 分段错误
【发布时间】:2017-02-16 18:08:10
【问题描述】:

我正在开发一个应用程序,该应用程序应检查计算机是否能够 ping google.com。为此,我使用 python subprocess 模块并发出调用,如下面的代码所示:

response = subprocess.call("ping -c 1 google.com -q", shell=True) 

但是,运行一段时间后,程序退出并出现分段错误。

我有以下代码:

daemon.py

def dataset_save(smartphone, mote):
print("DATA LOGGER:\tStarting Now")
with open('dataset.csv', 'a+') as dataset:
    dataset.write(str(datetime.datetime.today()) + ',' + \
            str(datetime.datetime.today().weekday()) + ',' + \
            str(smartphone.connected) + ',' + \
            str(mote.A0_pw) + ',' + \
            str(mote.B00_pw) + ',' + \
            str(mote.B01_pw) + ',' + \
            str(mote.B10_pw) + ',' + \
            str(mote.B11_pw) + ',' + \
            str(presence.get_value()) + ',' + \
            str(temperature.get_value()) + ',' + \
            str(luminosity.get_value()) + '\n')
    print("DATA LOGGER: \tData successfully logged @ %s!" %str(datetime.datetime.today()))
return


def run():
    check_internet()
    while True:
        dataset_save(smartphone, gateway)
        check_presence()

check_internet.py

def check_internet():
response = subprocess.call("ping -c 1 google.com -q", shell=True)
print(response)
if response == 0:
    print ("CONNECTIVITY: \tConnected to internet")
    threading.Timer(1, check_internet).start()
    return

else: 
    print("CONNECTIVITY: \tUnable to connect to internet")
    threading.Timer(1, check_internet).start()
    return

在 GDB 上运行它,我在分段错误时得到以下跟踪:

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 146.626/146.626/146.626/0.000 ms
0
CONNECTIVITY:   Connected to internet
[New Thread 0xb55ffb40 (LWP 4064)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb65ffb40 (LWP 4043)]
PING google.com (216.58.222.110) 56(84) bytes of data.
__deallocate_stack (pd=0xb65ffb40) at allocatestack.c:760
760 allocatestack.c: No such file or directory.
(gdb) 
--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 146.504/146.504/146.504/0.000 ms

(gdb) bt
#0  __deallocate_stack (pd=0xb65ffb40) at allocatestack.c:760
#1  0xb7fc3eab in start_thread (arg=0xb65ffb40) at pthread_create.c:427
#2  0xb7e8164e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
(gdb) 

我有什么理由不应该像我正在使用的那样使用 threding.Timer 吗?在我看来,线程的连续创建是造成这种分段错误的原因。

谢谢。

【问题讨论】:

  • 奇怪。您可以删除 shell=True 参数,因为它没有被使用。
  • @Jean-FrançoisFabre -- 删除 shell=True 会很好,但是您应该将参数作为列表而不是字符串传递。
  • 这些计时器线程不应该在某个时候得到.joined吗?
  • @mgilson 我对线程很陌生,我在网上看到的大多数示例都没有使用 .join。也许我错过了,我会调查一下。谢谢!

标签: python multithreading segmentation-fault


【解决方案1】:

您正在从计时器本身重新启动计时器,这可能不太好(使用线程进行递归调用,啊)。如果您对 ping 延迟的准确性要求不高,您实际上并不需要 Timer:您可以像这样启动一个循环并定期 ping google 的线程:

import threading,subprocess,time

def check_internet():
    while True:
        time.sleep(1)
        response = subprocess.call("ping -n 1 google.com".split())
        print(response)
        if response == 0:
            print("CONNECTIVITY: \tConnected to internet")
        else:
            print("CONNECTIVITY: \tUnable to connect to internet")

t=threading.Thread(target=check_internet)
t.start()

print("Started")
t.join()

您只创建 1 个线程,每 1 秒以上创建 1 个 ping 进程(它不是一个受监管的计时器,但应该足够了)。

编辑:没有ping 输出的版本:

import threading,subprocess,time

def check_internet():
    while True:
        time.sleep(1)
        p = subprocess.Popen("ping -n 1 google.com".split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        out,err = p.communicate()
        response = p.wait()
        if response == 0:
            print("CONNECTIVITY: \tConnected to internet")
        else:
            print("CONNECTIVITY: \tUnable to connect to internet")

t=threading.Thread(target=check_internet)
t.start()

print("Started")
t.join()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2019-07-05
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    相关资源
    最近更新 更多