leetcode 1115. 交替打印FooBar - python 实现多进程通信 PV 操作

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems
特别鸣谢:来自夸夸群的 醉笑陪公看落花@知乎王不懂不懂@知乎
感谢醉笑陪公看落花@知乎 倾囊相授,感谢小伙伴们督促学习,一起进步

参考文章:python3 的多线程操作 https://www.runoob.com/python3/python3-multithreading.html

我们提供一个类:

class FooBar {
public void foo() {
for (int i = 0; i < n; i++) {
print(“foo”);
}
}

public void bar() {
for (int i = 0; i < n; i++) {
print(“bar”);
}
}
}
两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。

请设计修改程序,以确保 “foobar” 被输出 n 次。

示例 1:

输入: n = 1
输出: “foobar”
解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,“foobar” 将被输出一次。
示例 2:

输入: n = 2
输出: “foobarfoobar”
解释: “foobar” 将被输出两次。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/print-foobar-alternately

题目分析

  • 先输出 foo,再输出bar
  • 在初始状态下,阻塞bar,让foo先执行
  • 执行一个之后,解开另一个的阻塞

threading.Semaphore(1) 表示有一个可用资源
threading.Semaphore(0) 表示当前没有可用资源

用这两个信号量实现pv 操作

  • acquire() 相当于P操作,申请资源
  • release() 相当于V操作,释放资源

题解 - 库函数调用信号量- 通过

import threading

class FooBar:
    def __init__(self, n):
        self.n = n
        self.s1 = threading.Semaphore(1)
        self.s2 = threading.Semaphore(0)

    def foo(self, printFoo: 'Callable[[], None]') -> None:
        
        for i in range(self.n):
            self.s1.acquire()
            # printFoo() outputs "foo". Do not change or remove this line.
            printFoo()
            self.s2.release()


    def bar(self, printBar: 'Callable[[], None]') -> None:
        
        for i in range(self.n):
            self.s2.acquire()
            # printBar() outputs "bar". Do not change or remove this line.
            printBar()
            self.s1.release()

            

题解 - 手动实现信号量操作 - 超时

python3 如何启动多个线程呢

tips:

  • thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。
  • 传参的时候,函数的参数用tuple传入,_thread.start_new_thread(fb.foo,(printFoo,))

import _thread


class FooBar:
    def __init__(self, n):
        self.n = n
        self.s1 = False
        self.s2 = True

    def foo(self, printFoo: 'Callable[[], None]') -> None:

        for i in range(self.n):
            while self.s1: pass
            # printFoo() outputs "foo". Do not change or remove this line.
            printFoo()
            self.s2 = False
            self.s1 = True

    def bar(self, printBar: 'Callable[[], None]') -> None:

        for i in range(self.n):
            while self.s2: pass
            # printBar() outputs "bar". Do not change or remove this line.
            printBar()
            self.s1 = False
            self.s2 = True


# for test the thread
def printFoo():
    print('foo', end='')
def printBar():
    print('bar', end='')
# 创建两个线程
fb = FooBar(3)
try:
   _thread.start_new_thread(fb.foo,(printFoo,))
   _thread.start_new_thread(fb.bar,(printBar,))

except:
    print("Error: unable to start thread")

while 1:pass

为什么没有 while 1:pass ,相关语句不能打印出来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值