V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
aice114
V2EX  ›  Python

请问一下有关 Python 多进程的问题

  •  
  •   aice114 · 2018-04-24 10:46:05 +08:00 · 2513 次点击
    这是一个创建于 2397 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问一下怎么能让下面的 my_process 只运行一次呢?我试过在类里面加进程锁,但是没用,小白请教一下各位大佬

    from multiprocessing import Process
    import time
    
    class ScheduleTest():
        @staticmethod
        def printx():
            while True:
                print('hello x')
                time.sleep(5)
    
        def run(self):
            print('printx is running...')
            my_process = Process(target=self.printx)
            my_process.start()
    
    
    def app_run():
        my_schedule = ScheduleTest()
        process_0 = Process(target=my_schedule.run)
        process_1 = Process(target=my_schedule.run)
        process_2 = Process(target=my_schedule.run)
        process_0.start()
        process_1.start()
        process_2.start()
    
    
    if __name__ == '__main__':
        app_run()
    
    12 条回复    2018-04-24 15:57:51 +08:00
    HypoChen
        1
    HypoChen  
       2018-04-24 10:47:51 +08:00   ❤️ 1
    信号量了解一下?
    aice114
        2
    aice114  
    OP
       2018-04-24 10:48:55 +08:00
    @HypoChen 我去瞅瞅
    qieqie
        3
    qieqie  
       2018-04-24 11:08:09 +08:00   ❤️ 1
    from multiprocessing import Process, Lock
    import time

    lock = Lock()

    class ScheduleTest():
    @staticmethod
    def printx(x):
    while True:
    try:
    lock.acquire()
    print('hello %d' % x)
    time.sleep(5)
    except:
    pass
    finally:
    lock.release()



    def run(self, pid):
    print('printx %d is running...' % pid)
    my_process = Process(target=self.printx, args=[pid])
    my_process.start()

    def app_run():
    my_schedule = ScheduleTest()
    process_0 = my_schedule.run(1)
    process_1 = my_schedule.run(2)
    process_2 = my_schedule.run(3)


    if __name__ == '__main__':
    app_run()
    qieqie
        4
    qieqie  
       2018-04-24 11:11:36 +08:00
    忘了写成 code block 了 - -
    aice114
        5
    aice114  
    OP
       2018-04-24 11:18:46 +08:00
    @qieqie 谢谢了啊,不过我那个需要 my_progress 在多进程的情况下只运行一次,也就是同时只有一个 printx 在运行,加锁的方式还是不行,3 个进程同时都在打印了
    SWBMESSI
        6
    SWBMESSI  
       2018-04-24 11:28:34 +08:00 via iPhone
    信号量.....操作系统了解一下?
    qieqie
        7
    qieqie  
       2018-04-24 11:53:51 +08:00
    @aice114 那不是更简单了么。。在运行进程之前非阻塞的 acquire(False),失败直接 return 就行了
    ai277014717
        8
    ai277014717  
       2018-04-24 11:59:40 +08:00
    python 有全局变量吗?写个 get 和 set 来控制全局变量,get set 加锁。
    my_process 之前 get 全局变量大于 1 就 return
    symons
        9
    symons  
       2018-04-24 13:58:00 +08:00
    借助 mysql 或者 mongodb 啥的来控制吗
    windardyang
        10
    windardyang  
       2018-04-24 15:36:21 +08:00   ❤️ 1
    #### 进程锁

    进程锁的位置很重要

    ```
    # -*- coding: utf-8 -*-
    from multiprocessing import Process, Lock
    import time


    lock = Lock()

    class ScheduleTest():
    @staticmethod
    def printx():
    while True:
    print('hello x')
    time.sleep(5)

    def run(self):
    print('printx is running...')
    my_process = Process(target=self.printx)
    my_process.start()


    def app_run():
    my_schedule = ScheduleTest()
    for i in range(3):
    with lock:
    p = Process(target=my_schedule.run)
    p.start()
    p.join()


    if __name__ == '__main__':
    app_run()

    ```

    #### 信号量

    信号量其实也是进程锁

    ```
    # -*- coding: utf-8 -*-
    from multiprocessing import Process, Semaphore
    import time


    s = Semaphore(1)


    class ScheduleTest():
    @staticmethod
    def printx():
    while True:
    print('hello x')
    time.sleep(5)

    def run(self):
    s.acquire()
    print('printx is running...')
    my_process = Process(target=self.printx)
    my_process.start()
    my_process.join()
    s.release()


    def app_run():
    my_schedule = ScheduleTest()
    process_0 = Process(target=my_schedule.run)
    process_1 = Process(target=my_schedule.run)
    process_2 = Process(target=my_schedule.run)
    process_0.start()
    process_1.start()
    process_2.start()


    if __name__ == '__main__':
    app_run()

    ```

    #### 共享变量

    共享变量注意需加锁

    ```
    # -*- coding: utf-8 -*-
    from multiprocessing import Process, Manager, Lock
    import time

    manager = Manager()
    sum = manager.Value('tmp', 0)
    lock = Lock()


    class ScheduleTest():
    @staticmethod
    def printx():
    while True:
    print('hello x')
    time.sleep(5)

    def run(self):
    with lock:
    if not sum.value:
    print('printx is running...')
    my_process = Process(target=self.printx)
    my_process.start()
    sum.value += 1
    else:
    print('printx has ran.')


    def app_run():
    my_schedule = ScheduleTest()
    process_0 = Process(target=my_schedule.run)
    process_1 = Process(target=my_schedule.run)
    process_2 = Process(target=my_schedule.run)
    process_0.start()
    process_1.start()
    process_2.start()


    if __name__ == '__main__':
    app_run()

    ```
    aice114
        11
    aice114  
    OP
       2018-04-24 15:49:21 +08:00
    @windardyang 谢谢,灰常详细了,我仔细研究研究
    woosdaf
        12
    woosdaf  
       2018-04-24 15:57:51 +08:00
    厉害
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5389 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 05:50 · PVG 13:50 · LAX 21:50 · JFK 00:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.