Python多线程生产者使用者模式

时间:2019-02-02 02:01:43

标签: python-3.x multithreading

我仍在学习如何编码,这是我第一次尝试多线程。 我读了很多多线程文章。我认为这些非常有帮助。

https://stackoverflow.com/questions/11196367/processing-single-file-from-multiple-processes
https://pymotw.com/2/multiprocessing/basics.html
https://www.agiliq.com/blog/2013/10/producer-consumer-problem-in-python/
https://docs.python.org/3/library/multiprocessing.html

有很多要考虑的问题。特别是对于初学者。 不幸的是,当我尝试将这些信息付诸实践时。我的代码工作不正常。

此代码背后的想法是读取simple.txt,其中包含用逗号分隔的数字行。例如:0.275,0.28,0.275,0.275,36078。 生产者线程读取每一行,并从该行的末尾删除换行符。然后,将行中的每个数字拆分并分配一个变量。 然后将Variable1放入队列。 使用者线程将拾取队列中的项目,将其平方,然后在日志文件中添加一个条目。

我正在使用的代码来自此模板:

https://www.bogotobogo.com/python/Multithread/python_multithreading_Synchronization_Producer_Consumer_using_Queue.php

这是我到目前为止的代码:

import threading
import queue
import time
import logging
import random
import sys

read_file = 'C:/temp/temp1/simplified.txt'
log1 = open('C:/temp/temp1/simplified_log1.txt', "a+")

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)

BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)

class ProducerThread(threading.Thread):
    def __init__(self, name, read_file):
        super(ProducerThread,self).__init__()
        self.name = name
        self.read_file = read_file

    def run(self, read_file):
        while True:
            if not q.full():
                with open(read_file, 'r') as f:
                    for line in f:
                        stripped = line.strip('\n\r')
                        value1,value2,value3,value4,value5,value6,value7 = stripped.split(',')
                        q.put(value1)
                        logging.debug('Putting ' + str(value1) + ' : ' + str(q.qsize()) + ' items in queue')
                        time.sleep(random.random())
        return

class ConsumerThread(threading.Thread):
    def __init__(self, name, value1, log1):
        super(ConsumerThread,self).__init__()
        self.name = name
        self.value1 = value1
        self.log1 = log1
        return

    def run(self):
        while True:
            if not q.empty():
                value1 = q.get()
                sqr_value1 = value1 * value1
                log1.write("The square of " + str(value1) + " is " + str(sqr_value1))
                logging.debug('Getting ' + str(value1) + ' : ' + str(q.qsize()) + ' items in queue')
                time.sleep(random.random())
        return

if __name__ == '__main__':

    p = ProducerThread(name='producer')
    c = ConsumerThread(name='consumer')

    p.start()
    time.sleep(2)
    c.start()
    time.sleep(2)

运行代码时,出现此错误:

Traceback (most recent call last):
  File "c:/Scripta/A_Simplified_Producer_Consumer_Queue_v0.1.py", line 60, in <module>
    p = ProducerThread(name='producer')
TypeError: __init__() missing 1 required positional argument: 'read_file'

我不知道我还需要在哪里添加“ read_file”。 任何帮助将不胜感激。预先感谢。

2 个答案:

答案 0 :(得分:2)

您的ProducerThread类需要两个参数(nameread_file)作为其__init__方法中定义的构造函数的参数,在该方法中,您仅提供第一个这样的参数在主块中创建实例时。您的第二堂课也有同样的问题。

您应该在创建实例时将read_file提供给构造函数,或者只是从构造函数签名中将其删除,因为您似乎并没有使用它(您可以使用{{ 1}}函数,但我认为这是不正确的。似乎您正在尝试从Thread超类重写该方法,并且我怀疑采用这样的参数。

答案 1 :(得分:0)

感谢您userSeventeen设置我在正确的道路上。 我认为,为了使用外部变量,我需要将它们放置在 init 方法中,然后再放入run方法中。你已经澄清,我只需要使用变量在运行方法。 这是工作代码。我不得不删除while true:语句,因为我不希望代码永远运行。

import threading
import queue
import time
import logging
import random
import sys
import os


read_file = 'C:/temp/temp1/simplified.txt'
log1 = open('C:/temp/temp1/simplified_log1.txt', "a+")

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-9s) %(message)s',)

BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)

class ProducerThread(threading.Thread):
    def __init__(self, name):
        super(ProducerThread,self).__init__()
        self.name = name

    def run(self):
        with open(read_file, 'r') as f:
            for line in f:
                stripped = line.strip('\n\r')
                value1,value2,value3,value4,value5 = stripped.split(',')
                float_value1 = float(value1)
                if not q.full():
                    q.put(float_value1)
                    logging.debug('Putting ' + str(float_value1) + ' : ' + str(q.qsize()) + ' items in queue')
                    time.sleep(random.random())
        return

class ConsumerThread(threading.Thread):
    def __init__(self, name):
        super(ConsumerThread,self).__init__()
        self.name = name
        return

    def run(self):
        while not q.empty():
            float_value1 = q.get()
            sqr_value1 = float_value1 * float_value1
            log1.write("The square of " + str(float_value1) + " is " + str(sqr_value1))
            logging.debug('Getting ' + str(float_value1) + ' : ' + str(q.qsize()) + ' items in queue')
            time.sleep(random.random())
        return

if __name__ == '__main__':

    p = ProducerThread(name='producer')
    c = ConsumerThread(name='consumer')

    p.start()
    time.sleep(2)
    c.start()
    time.sleep(2)
相关问题