2016-10-07 2 views
4

Я разрабатываю приложение, которое должно проверить, способен ли компьютер выполнить ping google.com. Для этого я использую модуль подпроцесс питона и выдает вызов, как показано в коде ниже:Ошибка сегментации Python при переключении потока

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, как я использую? Мне кажется, что последовательное создание потоков отвечает за эту ошибку сегментации.

Спасибо.

+0

странно. Вы можете удалить параметр 'shell = True', поскольку он не используется. –

+0

@ Jean-FrançoisFabre - Отбрасывание 'shell = True' было бы хорошим, но тогда вы должны передать аргументы как список, а не строку. – mgilson

+0

Должны ли эти таймерные нити в конечном итоге получить '.join'ed в какой-то момент? – mgilson

ответ

0

Вы переворачиваете таймер из самого таймера, который может быть не слишком хорошим (рекурсивный вызов с потоками, argh). Вам не нужно Timer, если вы не слишком требовательны о точности задержки пинг: вы могли бы начать что-нить петли и пинги 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+ секунды (это не регулируемый таймер, но этого должно быть достаточно).

EDIT: версия без 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()