【Python】线程的创建、执行、互斥、同步、销毁

还是《【Java】利用synchronized(this)完成线程的临界区》(点击打开链接)、《【Linux】线程互斥》(点击打开链接)、《【C++】Windows线程的创建、执行、互斥、同步、销毁》(点击打开链接)中的设置多个线程对一个ticket进行自减操作,用来说明Python中多线程的运用,涉及的创建、执行、互斥、同步、销毁问题。

运行结果如下,还是差不多,运行三次,每次的运行结果,每个线程最终的得票结果是不同的,但是4个线程最终“得票”的总和为 ticket 最初设置的值为100000,证明这4个线程成功实现了互斥。




虽然每次运行结果是不同,但是可以看得出每次运行结果大抵上是平均的。貌似Python对线程作系统资源的处理,比Java要好。

然而,Python总要实现多线程,代码并不像想象中简单,具体如下:

# -*-coding:utf-8-*-
import threading;
mutex_lock = threading.RLock();  # 互斥锁的声明
ticket = 100000;  # 总票数
# 用于统计各个线程的得票数
ticket_for_thread1 = 0;
ticket_for_thread2 = 0;
ticket_for_thread3 = 0;
ticket_for_thread4 = 0;
   
class myThread(threading.Thread):  # 线程处理函数
    def __init__(self, name): 
        threading.Thread.__init__(self);  # 线程类必须的初始化
        self.thread_name = name;  # 将传递过来的name构造到类中的name
    def run(self):
        # 声明在类中使用全局变量
        global mutex_lock;
        global ticket;
        global ticket_for_thread1;
        global ticket_for_thread2;
        global ticket_for_thread3;
        global ticket_for_thread4;      
        while 1:
            mutex_lock.acquire();  # 临界区开始,互斥的开始
            # 仅能有一个线程↓↓↓↓↓↓↓↓↓↓↓↓             
            if ticket > 0:                
                ticket -= 1;
                # 统计哪到线程拿到票
                print "%s抢到了票!票还剩余:%d。" % (self.thread_name, ticket);                
                if self.thread_name == "线程1":
                    ticket_for_thread1 += 1;
                elif self.thread_name == "线程2":
                    ticket_for_thread2 += 1;
                elif self.thread_name == "线程3":
                    ticket_for_thread3 += 1;                    
                elif self.thread_name == "线程4":
                    ticket_for_thread4 += 1;                                                
            else:                
                break;
            # 仅能有一个线程↑↑↑↑↑↑↑↑↑↑↑↑
            mutex_lock.release();  # 临界区结束,互斥的结束
        mutex_lock.release();  # python在线程死亡的时候,不会清理已存在在线程函数的互斥锁,必须程序猿自己主动清理
        print "%s被销毁了!" % (self.thread_name);  
              
# 初始化线程 
thread1 = myThread("线程1");
thread2 = myThread("线程2");  
thread3 = myThread("线程3"); 
thread4 = myThread("线程4");
# 开启线程 
thread1.start();
thread2.start(); 
thread3.start();
thread4.start();
# 等到线程1、2、3、4结束才进行以下的代码(同步) 
thread1.join();
thread2.join(); 
thread3.join();
thread4.join(); 
print "票都抢光了,大家都散了吧!";
print "=========得票统计=========";  
print "线程1:%d张" % (ticket_for_thread1);  
print "线程2:%d张" % (ticket_for_thread2);
print "线程3:%d张" % (ticket_for_thread3);
print "线程4:%d张" % (ticket_for_thread4);

1、从上面的代码可以看出,在Python2.7中要使用线程必须使用threading而不是古老的thread模块。

如果你像网上部分遗留依旧的文章一样,在Python2.7中使用thread来实现线程,至少在Eclipse的Pydev中会报错:sys.excepthook is missing,lost sys.stderr如下图所示:


所以必须使用现时Python建议使用的threading。

2、与其它编程语言类似,声明一个互斥锁,与一系列的得票数。之后,与Java同样地,Python实现线程的函数,是要重写一个类。而类中使用全局变量,则与同为脚本语言的php一样《【php】global的使用与php的全局变量》(点击打开链接),要用global才能使用这个全局变量,而不是C/C++可以直接使用。

3、需要注意的,Python需要在线程跑完class myThread(threading.Thread)这个类的def run(self)方法之前,必须自己手动清理互斥锁,它不会像其它编程语言那样,说线程跑完def run(self)方法,会自然而然地清理该线程被创建的互斥锁。如果没有最后一句手动清理互斥锁,则会造成死锁。

4、最后与其它编程语言一样了,利用线程的join方法可以等待这个线程跑完def run(self)方法中的所有代码,才执行之后的代码,实现同步。否则主函数中的代码,相当于与父线程。主函数开启的线程,相当于其子线程,互不影响的。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python线程编程是指在Python中使用多个线程同时执行任务的技术。由于Python中的全局解释器锁(Global Interpreter Lock,简称GIL)的限制,Python线程并不能真正地实现多核并行,但是可以通过多线程来提升程序的响应速度和并发处理能力。 Python中的多线程编程可以使用threading模块来实现,该模块提供了Thread类来创建和管理线程。下面是一个简单的例子: ```python import threading def worker(): print("I am running in thread", threading.current_thread().name) threads = [] for i in range(5): t = threading.Thread(target=worker) threads.append(t) t.start() for t in threads: t.join() ``` 这段代码创建了5个线程,并让它们同时执行worker函数。在worker函数中,调用了threading.current_thread().name函数来打印当前线程的名称。最后,主线程等待所有子线执行完毕后再退出。 Python线程编程需要注意以下几点: 1. 多线程并不能真正地实现多核并行,因为Python中的全局解释器锁限制了同一时间只能有一个线执行Python字节码。 2. 多线程共享进程的内存空间,需要注意线程安全问题,例如多个线程同时访问同一个共享变量可能会出现数据竞争的问题。 3. Python中的多线程可以通过锁机制来实现线程间的同步互斥,避免数据竞争的问题。常用的锁包括互斥锁、读写锁、信号量等。 4. 在使用多线程编程时,需要考虑线程的创建销毁线程间的通信和同步等问题,需要综合考虑程序的性能和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值