Работает только одна программа python (например, Firefox)?

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

firefox http://somewebsite

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

processStuff.py file/url

затем вызов:

processStuff.py anotherfile

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

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

Ответ 1

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

Вот наивная реализация, чтобы проиллюстрировать мою точку зрения. При первом запуске создается файл сокета lock.sock. Дальнейшие запуски script обнаружат блокировку и отправят ей 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, но это вне этого вопроса. Руководство по программированию Socket Python также может помочь вам. У меня нет машины Windows, поэтому я не могу подтвердить, что она работает на этой платформе.

Ответ 2

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

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

Существует много разных способов, в зависимости от того, на какой платформе запускается программа.

Ответ 3

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

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

File System Message Relay

Ответ 4

Я думаю, вы могли бы использовать многопроцессорные соединения с subprocess для этого. Ваш script просто должен попытаться подключиться к соединению "remote" на локальном хосте, а если он недоступен, он может запустить его.