Как делать запросы во время выполнения программы в бесконечном цикле с многопроцессорной обработкой - PullRequest
0 голосов
/ 01 июля 2019

У меня есть две функции, которые должны работать одновременно.read_card должен работать в бесконечном цикле и ждать новых карточек (на самом деле это считыватель Nrf) и добавляет некоторую строку в очередь, send_data предполагается получить значения из очереди и отправить их на сервер через библиотеку запросов.Все работает, когда я не использую многопроцессорность.Но мне нужен параллелизм, я думаю.

Вот мои две функции.

def read_card(reader, configs):
    print("First started")
    while True:
        authorized_uid = reader.is_granted(reader.read())
        print("Waiting for card")
        #TODO:If not authorized in AccessList.txt look to the server
        if authorized_uid is not None:
            print(authorized_uid)
            open_door()
            check_model = CheckModel(configs.DeviceSerialNumber, authorized_uid)
            message_helper.put_message(check_model)

def send_data(sender):
    print("Second started")
    while True:
        message_model = message_helper.get_message()
        if message_model is not None:
            sender.send_message(message_model)

Вот как я называю main

def main():
    download_settings()
    create_folders()
    settings = read_settings()
    accessList = get_user_list(settings)
    configure_scheduler(settings)  

    message_sender = MessageSender(client.check,client.bulk)

    reader_process = multiprocessing.Process(name = "reader_loop", target = read_card, args=(Reader(accessList, entryLogger),configs,))
    message_process = multiprocessing.Process(name = "message_loop", target = send_data, args=(message_sender,))
    reader_process.start()
    message_process.start()

if __name__ == '__main__':
    main()

И это для отладки.Я напечатал, что put_message и send_message из разных классов.

def send_message(self,model):
    print(model)
    return self.checkClient.check(model)

def put_message(self, message):
    print(message)
    self.put_to_queue(self.queue, message)
    self.put_to_db(message)

Я ожидаю увидеть некоторые имена объектов в терминале, но я вижу только ниже.Также не работает ридер.

First started
Second started

Какую часть я делаю не так?

1 Ответ

0 голосов
/ 01 июля 2019

Используйте Queue для связи между процессами. Затем, когда вы читаете карточку внутри reader, создаете новое задание и помещаете его в очередь, затем вставляете это задание в процессор и отправляете запрос.

Вот подтверждение концепции:

from datetime import datetime
from multiprocessing import Process, Queue
from random import random
from time import sleep

import requests


def reader(q: Queue):
    while True:
        # create a job
        job = {'date': datetime.now().isoformat(), 'number': random()}
        q.put(job)
        # use a proper logger instead of printing,
        # otherwise you'll get mangled output!
        print('Enqueued new job', job)
        sleep(5)


def client(q: Queue):
    while True:
        # wait for a new job
        job = q.get()
        res = requests.post(url='https://httpbin.org/post',
                            data=job)
        res.raise_for_status()
        json = res.json()
        print(json['form'])


if __name__ == '__main__':
    q = Queue()
    reader_proc = Process(name='reader', target=reader, args=(q,))
    client_proc = Process(name='client', target=client, args=(q,))

    procs = [reader_proc, client_proc]
    for p in procs:
        print(f'{p.name} started')
        p.start()
    for p in procs:
        p.join()

который печатает:

reader started
client started
Enqueued new job {'date': '2019-07-01T15:51:53.100395', 'number': 0.7659293922700549}
{'date': '2019-07-01T15:51:53.100395', 'number': '0.7659293922700549'}
Enqueued new job {'date': '2019-07-01T15:51:58.116020', 'number': 0.14306347124900576}
{'date': '2019-07-01T15:51:58.116020', 'number': '0.14306347124900576'}
...