Работает только одна программа на Python (например, Firefox)? - PullRequest
14 голосов
/ 09 августа 2011

Когда я открываю Firefox, затем запускаю команду:

firefox http://somewebsite

URL открывается в новой вкладке Firefox (то же самое происходит и с Chromium). Есть ли способ воспроизвести это поведение в Python? Например, позвонив по телефону:

processStuff.py file/url

затем позвонив:

processStuff.py anotherfile

не должен запускать два разных процесса, но отправляет сообщение запущенной в данный момент программе. Например, у вас может быть информация в одном диалоговом окне с вкладками вместо 10 отдельных окон.

Добавление награды для всех, кто может описать как Firefox / Chromium делают это кросс-платформенным способом.

Ответы [ 5 ]

24 голосов
/ 13 августа 2011

Firefox делает это следующим образом: первый экземпляр создает файл сокета (или именованный канал в Windows). Это служит как способом для следующих экземпляров Firefox обнаружить и связаться с первым экземпляром, так и переслать ему URL-адрес перед смертью. Файл сокета или именованный канал доступны только для процессов, работающих в локальной системе (как файлы), никакой сетевой клиент не может иметь к нему доступ. Поскольку они являются файлами, брандмауэры также не будут их блокировать (это похоже на запись в файл).

Вот наивная реализация, иллюстрирующая мою точку зрения. При первом запуске создается файл сокета lock.sock. Дальнейшие запуски скрипта обнаружат блокировку и отправят на нее URL:

import socket
import os

SOCKET_FILENAME = 'lock.sock'

def server():
    print 'I\'m the server, creating the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.bind(SOCKET_FILENAME)

    try:
        while True:
            print 'Got a URL: %s' % s.recv(65536)
    except KeyboardInterrupt, exc:
        print 'Quitting, removing the socket file'
        s.close
        os.remove(SOCKET_FILENAME)

def client():
    print 'I\'m the client, opening the socket'
    s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    s.connect(SOCKET_FILENAME)
    s.send('http://stackoverflow.com')
    s.close()

def main():
    if os.path.exists(SOCKET_FILENAME):
        try:
            client()
        except (socket.error):
            print "Bad socket file, program closed unexpectedly?"
            os.remove(SOCKET_FILENAME)
            server()
    else:
        server()

main()

Вы должны реализовать правильный протокол (например, отправлять правильные дейтаграммы вместо жесткого кодирования длины), возможно, используя SocketServer , но это за пределами этого вопроса. Python Socket Programming Howto также может помочь вам. У меня нет компьютера с Windows, поэтому я не могу подтвердить, что он работает на этой платформе.

8 голосов
/ 09 августа 2011

Вы можете создать каталог данных, в котором вы создадите «файл блокировки», когда ваша программа будет запущена, после проверки, если файл еще не существует.

Если он существует, вы должны попытаться установить связь с существующим процессом, который создает сокет или канал или что-то в этом роде и соответствующим образом сообщает свой адрес или путь.

Есть много разных способов сделать это, в зависимости от платформы, на которой работает программа.

2 голосов
/ 12 августа 2011

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

2 голосов
/ 12 августа 2011

Хотя я сомневаюсь, что именно так Firefox / Chrome делает это, было бы возможно заархивировать вашу цель без сокетов и полагаясь исключительно на файловую систему.Мне было трудно вставить текст, поэтому ниже приведена блок-схема грубого , как это можно сделать.Я бы посчитал этот подход похожим на куки :).Еще одна мысль на этот счет заключается в том, что с этим можно хранить рабочие области или вкладки в нескольких сеансах.

РЕДАКТИРОВАТЬ
За комментарий, переменные среды не разделяются между процессами.До сих пор вся моя работа была одним процессом, вызывающим несколько модулей.Извините за путаницу.

File System Message Relay

1 голос
/ 09 августа 2011
  1. Очень просто использовать розетки.
  2. http://wiki.python.org/moin/ParallelProcessing
  3. Использовать потоки, http://www.valuedlessons.com/2008/06/message-passing-conccurrency-actor.html

Пример для программирования сокетов: http://code.activestate.com/recipes/52218-message-passing-with-socket-datagrams/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...