Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 8, 2009 04:27:47

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Повторый запуск

Значит так.

Есть программа. Написанна на питоне 2.6 с PyQt4 и весело собранна py2exe.
Мне нужно, чтобы при повторном запуске этой программы, она передавала работающему экземпляру параметры с которыми запущена и выключалась.
Вопрос связан с IPC, но как его лучше реализовать в столь ограниченном объёме – попадать наковальней по таракану и запускать какой-нить DBus в данном случае считаю идиотизмом.
Есть мысль взять QtCore.QSystemSemaphore и работать с каким-нить lock-файлом или QtCore.QSharedMemory

Я никогда этим не занимался, поэтому спрашиваю у вас совета о том, как лучше поступить в данной ситуации.



Офлайн

#2 Июнь 8, 2009 07:53:49

hellslade
От:
Зарегистрирован: 2008-01-28
Сообщения: 240
Репутация: +  0  -
Профиль   Отправить e-mail  

Повторый запуск

Может вот так?

#
import sys
import thread,socket
from PyQt4 import QtCore,QtGui
HOST='localhost'
PORT= 50008
class InstanceChecker(QtCore.QThread):
''' class detects second copy of program in memory.
'''
def __init__(self, parent=None):
super(InstanceChecker, self).__init__(parent)
def run(self):
self.InstallSocketHandler()

def SendData(self):
''' call this method to send data to first running instance
'''
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send('Hello first copy!.This is from second copy!')
s.close()

def InstallSocketHandler(self):
print "creating local socket..."
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connectionStatus = False
try:
s.bind((HOST, PORT))
self.connectionStatus=True
except socket.error:
print "socket error!"
# send data through socket to first copy
self.SendData()
self.emit(QtCore.SIGNAL("status"),'busy')
if self.connectionStatus:
self.emit(QtCore.SIGNAL("status"),'ok')
s.listen(1)
while 1:
conn, addr = s.accept()
data = conn.recv(1024)
self.emit(QtCore.SIGNAL("datareceived"),data)
if data == 'end': break
conn.close()


def datareceiver(data):
print "receiving data from second copy :",data
# raise window from minimized(possibly) state
form.showNormal()
def signalreceiver(data):
print "signal received:",data
if data == 'busy':
print "First copy detected in memory : exiting now."
sys.exit(1)

if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
app.instanceChecker = InstanceChecker()
app.instanceChecker.start()


app.connect(app.instanceChecker,QtCore.SIGNAL("status"),signalreceiver)
app.connect(app.instanceChecker,QtCore.SIGNAL("datareceived"),datareceiver)

global form
form = QtGui.QMainWindow(None)
form.show()
app.exec_()



Офлайн

#3 Июнь 8, 2009 23:49:39

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Повторый запуск

Я думал о таком подходе. Даже больше скажу, это была первая мысль, которая пришла мне в голову. Но что-то она мне не нравится:
1. Мы открали порт и кто угодно может передать нам любые параменты, которые могут оказаться не очень нужны юзеру. Т.е. это дыра в безопастности;
2. Внутренняя защита может не дать юзеру открыть порт. И правильно сделает. Хотя это и редкость…

Ладно, попробую через QtCore.QSharedMemory. Может чего и получится.



Офлайн

#4 Июнь 9, 2009 00:07:59

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Повторый запуск

Порты лучше не брать в качестве объекта блокировки. Если процесс грохнется, ОСь не сразу освободит этот порт, а только после некоторого временного промежутка, во время которого невозможно будет перезапустить упавшее приложение. Для винды в качестве объекта блокировки я юзал мьютексы.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version