繁体   English   中英

无法在 Python 中使用我的 class 实例进行多处理

[英]Can't get multiprocessing to work with my class instances in Python

基本上我想制作几个相同的 object 实例并同时分别执行它们。 示例代码:

class Student:

    def __init__(self, username_, password_):
        self.username = username_
        self.password = password_
        self.driver = webdriver.Chrome('chromedriver.exe')

    def login(self):
        # Go to students page
        self.driver.get('https://www.students.com/')
        time.sleep(2)

        # Enter username in login form
        enter_username = WebDriverWait(self.driver, 20).until(
            expected_conditions.presence_of_element_located((By.NAME, 'username')))
        enter_username.send_keys(self.username)
        # Enter password in login form
        enter_password = WebDriverWait(self.driver, 20).until(
            expected_conditions.presence_of_element_located((By.NAME, 'password')))
        enter_password.send_keys(self.password)

        # Wait to send the form
        time.sleep(2)

        # Click Log In button
        self.driver.find_elements_by_xpath("//div[contains(text(), 'Iniciar sesión')]")[0].click()

        # Wait for the form to be sent
        time.sleep(5)
        self.start_working()
        # This functions is and endless loop that simulates work

if __name__ == '__main__':
            load_dotenv()

            query = "SELECT username, password FROM students"
            cursor.execute(query)
            records = cursor.fetchall()

            print("Total number of accounts botting up ", cursor.rowcount)

            object_list = list()
            for username, password in records:
                obj = Student(username, password)
                object_list.append(obj)

            instance_list = list()
            for x in object_list:
                p = multiprocessing.Process(target=x.login)
                p.start()
                instace_list.append(p)

            for x in instance_list:
                x.join()

到目前为止,我已经让他们都创建了 class 的实例,但是我无法为每个实例执行登录方法。

我在终端中收到此错误:

 (student-bot) C:\python\student-bot>Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
    new_handle = reduction.steal_handle(parent_pid, pipe_handle)
  File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\reduction.py", line 87, in steal_handle
    _winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
PermissionError: [WinError 5] Acceso denegado
[13852:1860:0427/193022.541:ERROR:device_event_log_impl.cc(162)] [19:30:22.541] Bluetooth: bluetooth_adapter_winrt.cc:1055 Getting Default Adapter failed.


您可能想要target=x.login ,而不是x.login() 否则,您将调用target.login()返回的任何内容,甚至可能无法调用。 一个“正在执行”的进程实际上可能只是主线程,并且是您编写x.login()的结果,但实际上没有一个子进程在工作。 显示错误消息会很有帮助。 还要确保上面的代码在一个开始的块内:

if __name__ == '__main__':

例如:

import multiprocessing

class Foo:
    def bar(self, i):
        print(i, flush=True)

f = Foo()

if __name__ == '__main__':
    instace_list = list()
    for i in range(3):
        p = multiprocessing.Process(target=f.bar, args=(i,))
        p.start()
        instace_list.append(p)

    for x in instace_list:
        x.join()

印刷:

0
1
2

更新

理想情况下,您的文件应该这样构造:

import blah, blah, blah;

class Student: # or perhaps this is imported above
    # definition of this class

def foo():
    # definition of foo

def bar():
    #d definition of bar

def query_database():
        load_dotenv()
        # obtain connection and cursor (code not shown)
        query = "SELECT username, password FROM students"
        cursor.execute(query)
        records = cursor.fetchall()

        print("Total number of accounts botting up ", cursor.rowcount)

        object_list = list()
        for username, password in records:
            obj = Student(username, password)
            object_list.append(obj)

        return object_list

if __name__ == '__main__':
        object_list = query_database() # get Student list
        with multiprocessing.Pool(processes=8) as pool:
            instance_list = list()
            for x in object_list:
                result = pool.apply_async(x.login)
                instance_list.append(result)

            for result in instance_list:
                result.get() # return value from login, which is None

更新 2

由于login方法似乎不是一个 cpu-bound 进程,您可以考虑使用线程。 此代码不必在__main__块内(尽管这样做是完全正确的):

from concurrent.futures import ThreadPoolExecutor

object_list = query_database() # get Student list
with ThreadPoolExecutor(max_workers=8) as executor:
    instance_list = list()
    for x in object_list:
        future = executor.submit(x.login)
        instance_list.append(future)

    for future in instance_list:
        future.get() # return value from login, which is None

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM