程序在多处理中无限期运行

问题描述 投票:0回答:1
import multiprocessing
from PIL import Image

name = input("Enter the file name: ")

def decode_file(filename):
    with open(filename, mode='rb') as file:
        binary_data = file.read()

    binary_list = []
    for byte in binary_data:
        binary_list.append(format(byte, '08b'))
    return binary_list

binary_list = decode_file(name)

l = len(binary_list)
no_of_bytes = l // 8

def make_row_list():
    row_list = []
    for i in range(0, l, 135):
        row_list.append(binary_list[i:i + 135])
    return row_list

row_list = make_row_list()

def fill_row(shared_pixels, width, row_data, count):
    x_coordinate = 0
    for byte in row_data:
        for bit in byte:
            index = x_coordinate + count * width
            shared_pixels[index] = int(bit)
            x_coordinate += 1

def fill_img(width, height):
    shared_pixels = multiprocessing.Array('i', width * height)
    processes = []
    count = 0
    for row_data in row_list:
        p = multiprocessing.Process(target=fill_row, args=(shared_pixels, width, row_data, count))
        p.start()
        processes.append(p)
        count += 1
    for process in processes:
        process.join()
    return shared_pixels

def create_img():
    width, height = 1080, 1920
    image = Image.new('1', (width, height))

    if no_of_bytes <= 135:
        x_coordinate = 0
        for byte in binary_list:
            for bit in byte:
                image.putpixel((x_coordinate, 0), int(bit))
                x_coordinate += 1
    elif no_of_bytes <= 259200:
        shared_pixels = fill_img(width, height)
        for y in range(height):
            for x in range(width):
                image.putpixel((x, y), shared_pixels[x + y * width])

    image.save('hi.png')
    image.show()

create_img()

当我运行这个程序时,它会询问文件名,然后无限期地不断询问文件名。在我添加多处理之前,程序运行良好。所以我认为这应该归咎于多处理。我是多处理新手,因此我们将不胜感激任何帮助:D

python multiprocessing
1个回答
0
投票

发生这种情况是因为在 Python 中,当您使用

multiprocessing
模块创建新进程时,每个新进程都会通过导入主模块来启动,其中包括再次执行
input
语句。

要解决此问题,请使用

input
块保护应运行一次的代码(如
if __name__ == "__main__":
语句和其他语句)。这样,代码在被新进程导入时就不会运行:

我向函数添加了必要的参数。这是一个工作版本:

import multiprocessing
from PIL import Image


def decode_file(filename):
    with open(filename, mode='rb') as file:
        binary_data = file.read()

    binary_list = []
    for byte in binary_data:
        binary_list.append(format(byte, '08b'))
    return binary_list


def make_row_list(binary_list):  # added binary_list
    row_list = []
    l = len(binary_list)
    for i in range(0, l, 135):
        row_list.append(binary_list[i:i + 135])
    return row_list


def fill_row(shared_pixels, width, row_data, count):
    x_coordinate = 0
    for byte in row_data:
        for bit in byte:
            index = x_coordinate + count * width
            shared_pixels[index] = int(bit)
            x_coordinate += 1


def fill_img(width, height, row_list):  # added row_list
    shared_pixels = multiprocessing.Array('i', width * height)
    processes = []
    count = 0
    for row_data in row_list:
        p = multiprocessing.Process(target=fill_row, args=(shared_pixels, width, row_data, count))
        p.start()
        processes.append(p)
        count += 1
    for process in processes:
        process.join()
    return shared_pixels


def create_img(binary_list, no_of_bytes):  # added binary_list and no_of_bytes
    width, height = 1080, 1920
    image = Image.new('1', (width, height))

    if no_of_bytes <= 135:
        x_coordinate = 0
        for byte in binary_list:
            for bit in byte:
                image.putpixel((x_coordinate, 0), int(bit))
                x_coordinate += 1
    elif no_of_bytes <= 259200:
        # calling make_row_list here
        row_list = make_row_list(binary_list)
        shared_pixels = fill_img(width, height, row_list)
        for y in range(height):
            for x in range(width):
                image.putpixel((x, y), shared_pixels[x + y * width])

    image.save('hi.png')
    image.show()


if __name__ == "__main__":
    name = input("Enter the file name: ")
    binary_list = decode_file(name)
    no_of_bytes = len(binary_list) // 8
    create_img(binary_list, no_of_bytes)
© www.soinside.com 2019 - 2024. All rights reserved.