Форум программистов, компьютерный форум, киберфорум
Фаер
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Python. Каналы.

Запись от Фаер размещена 02.11.2012 в 19:29
Показов 9470 Комментарии 0

Очереди и стеки, разобранные Нами в прошлой записи, далеко не единственный метод общения между потоками. Для передачи данных можно также использовать каналы - более низкоуровневый механизм. Каналы, или трубы(от названия соответствующей функции/класса - pipe()), можно найти в системном модуле os.

Сначала изготовим такой скрипт:

Python
1
2
3
4
5
6
7
import random
s1=random.randint(0,10)
s2=random.randint(0,10)
p=random.randint(0,10)
print(s1)
print(s2)
print('Done')
Генерируем три числа, два из них выводим в стандартный поток и заканчиваем всё это надписью 'Done'. Ничего сложного. Теперь закроем этот скрипт и запомним где он находится. Дальше пишите команды где хотите - в отдельном файле или прямо в IDLE:

Python
1
2
3
4
import os
pipe=os.popen('C:/Documents and Settings/Пользователь/Рабочий стол/script.py')
t=pipe.read()
print(t)
Функция os.popen(name) создаёт канал, через который методом read() Мы читаем данные, напечатанные программой name в стандартном потоке. В результате Вы должны получить что-то вроде:

Python
1
>>> '6\n2\nDone\n'
Где '\n' - символ перевода курсора на следующую строку. Возьмите на заметку, что Мы получили строку(str), в которой содержатся только те данные, которые Мы занесли в стандартный поток вывода с помощью print(), а это значит, что передать таким образом серьёзный объект невозможно. Ещё один нюанс: скрипт script.py запускается автоматически, в качестве дочернего потока.

Теперь пример посложнее, с другими трубами и с параллельными потоками:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from threading import Thread
from time import sleep
import os
pout,pin=os.pipe()
def f1():
    sleep(5)
    s='Hello,man!'.encode()
    os.write(pin,s)
def f2():
    t=os.read(pout,64)
    print(t.decode())
th=Thread(target=f1,args=())
th2=Thread(target=f2,args=())
th.start()
th2.start()
input()
Разберём поподробнее:

В строке
Python
1
pout,pin=os.pipe()
Мы, грубо говоря, создаём два конца одного и того же канала - с одной стороны пишем, с другой читаем. Заметьте, что первая переменная pout - конец, с которого будет производиться чтение. Отпечатав pin и pout, Вы увидите коды дескрипторов - концов трубы(pipe()).

При передаче данных через каналы, не забывайте кодировать эти самые данные(encode(),decode()) - иначе передачи не произойдёт. Кроме того, функции read() вторым аргументом нужно передать примерный размер читаемой строки байтов.
Так же обратите внимание на то, что функция os.read() приостанавливает выполнение потока th2 до тех пор, пока не будут получены данные.

Однако всё это, так сказать, мелочи жизни. Взаимодействие потоков между собой, несомненно, вещь полезная, но гораздо актуальнее научиться связывать между собой отдельные процессы, которые, как Нам уже известно, являются более высокоуровневым механизмом выполнения. Можно догадаться, что нужный Нам инструмент находится в модуле multiprocessing. Смотрим:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from multiprocessing import Pipe,Process
from time import sleep
import os
(pout,pin)=Pipe()
def f1(pin):
    sleep(3)
    s='Hello,man!'
    pin.send(s)
def f2(pout):
    t=pout.recv()
    print(t)
    
p1=Process(target=f1,args=(pin,))
p2=Process(target=f2,args=(pout,))
if __name__=='__main__':
    p1.start()
    p2.start()
    input()
Точно так же берём два конца pin и pout. Правда на этот раз при конструировании процессов их(концы) нужно передать каждому экземпляру класса Process().

Не забывайте, что при передаче одного аргумента нужна приблудная запятая, которая даёт понять Python'у, что это кортеж(tuple), а не просто выделяющие скобки.
Так же Вы, должно быть, заметили, что посылаем данные Мы с помощью метода send()(а не write()), а вот принимаем не самым легкозапоминающимся методом recv().

При передаче объектов между процессами кодировать их не нужно! (encode(),decode())
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru