专栏首页python前行者[python]多线程模块thread与threading

[python]多线程模块thread与threading

Python通过两个标准库(thread, threading)提供了对多线程的支持

thread模块

thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用”thread” 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。

import time  
import thread  

def runner(arg):  
    for i in range(6):  
        print str(i)+':'+arg  

        time.sleep(1)  
    #结束当前线程  
    thread.exit_thread()  #等同于thread.exit()  

#启动一个线程,第一个参数为函数名,  
#第二个参数为一个tuple类型,是传给函数的参数  
thread.start_new_thread(runner, ('hello world',))   #等同于thread.start_new(runner, ('hello world'))  

#创建一个锁,锁用于线程同步,通常控制对共享资源的访问  
lock = thread.allocate_lock()  #等同于thread.allocate()  
num = 0  
#获得锁,成功返回True,失败返回False  
if lock.acquire():  
    num += 1  
    #释放锁  
    lock.release()  
#thread模块提供的线程都将在主线程结束后同时结束,因此将主线程延迟结束  
time.sleep(10)  
print 'num:'+str(num)  

threading.Thread类的常用方法 1.在自己的线程类的__ init__里调用threading.Thread.__init__(self,name=threadname)threadname为线程的名字。 2.run(),通常需要重写,编写代码实现做需要的功能。 3.getName(),获得线程对象名称。 4.setName(),设置线程对象名称。 5.start(),启动线程。 6.join([timeout]),等待另一线程结束后再运行。 7.setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。 8.isDaemon(),判断线程是否随主线程一起结束。 9.isAlive(),检查线程是否在运行中。

要想创建一个线程对象,只要继承类threading.Thread,然后在__ init__里边调用threading.Thread.__init__()方法即可。重写run()方法,将要实现的功能放到此方法中即可。

class runner(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self)  
        self.name = name  
        self.thread_stop = False  
    def run(self):  
        while not self.thread_stop:  
            print str(self.name)+':'+'hello world'  
            time.sleep(1)  
    def stop(self):  
        self.thread_stop = True  

def test():  
    t = runner('thread')  
    t.start()  
    time.sleep(10)  
    t.stop()  

if __name__ == '__main__':  
    test()  

线程同步(锁)

最简单的同步机制就是锁。锁对象由threading.RLock类创建。线程可以使用锁的acquire()方法获得锁,这样锁就进入locked状态。每次只有一个线程可以获得锁。如果当另一个线程试图获得这个锁的时候,就会被系统变为blocked状态,直到那个拥有锁的线程调用锁的release()方法来释放锁,这样锁就会进入unlocked状态。blocked状态的线程就会收到一个通知,并有权利获得锁。

如果多个线程处于blocked状态,所有线程都会先解除blocked状态,然后系统选择一个线程来获得锁,其他的线程继续blocked。python的threading module是在建立在thread module基础之上的一个module,在thread module中,python提供了用户级的线程同步工具Lock对象。

而在threading module中,python又提供了Lock对象的变种: RLock对象。RLock对象内部维护着一个Lock对象,它是一种可重入的对象。对于Lock对象而言,如果一个线程连续两次进行acquire操作,那么由于第一次acquire之后没有release,第二次acquire将挂起线程。这会导致Lock对象永远不会release,使得线程死锁。

RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且每一次的acquire操作必须有一个release操作与之对应,在所有的release操作完成之后,别的线程才能申请该RLock对象。

我们把修改共享数据的代码称为临界区。必须将所有临界区都封闭在同一个锁对象的acquirerelease之间。

import time  
import threading  
num=0  
lock = threading.RLock()  
class runner(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self)  
        self.name = name  

    def run(self):  
        global num    
        while True:   
            if num >= 6: break  
            if lock.acquire():  
                print "Thread(%s) locked, Number: %d" % (self.name, num)    
                time.sleep(1)  
            lock.release()  
            print "Thread(%s) released, Number: %d" % (self.name, num)  
            time.sleep(1)  
            num += 1   

def test():  
    t1 = runner('thread1')  
    t2 = runner('thread2')  
    t1.start()  
    t2.start()  

if __name__== '__main__':    
    test()    

Python thread实现多线程

#-*- encoding: gb2312 -*-
import string, threading, time

def thread_main(a):
  global count, mutex
  # 获得线程名
  threadname = threading.currentThread().getName()

  for x in xrange(0, int(a)):
    # 取得锁
    mutex.acquire()
    count = count + 1
    # 释放锁
    mutex.release()
    print threadname, x, count
    time.sleep(1)

def main(num):
  global count, mutex
  threads = []

  count = 1
  # 创建一个锁
  mutex = threading.Lock()
  # 先创建线程对象
  for x in xrange(0, num):
    threads.append(threading.Thread(target=thread_main, args=(10,)))
  # 启动所有线程
  for t in threads:
    t.start()
  # 主线程中等待所有子线程退出
  for t in threads:
    t.join() 


if __name__ == '__main__':
  num = 4
  # 创建4个线程
  main(4)

Python threading实现多线程

#-*- encoding: gb2312 -*-
import threading
import time

class Test(threading.Thread):
  def __init__(self, num):
    threading.Thread.__init__(self)
    self._run_num = num

  def run(self):
    global count, mutex
    threadname = threading.currentThread().getName()

    for x in xrange(0, int(self._run_num)):
      mutex.acquire()
      count = count + 1
      mutex.release()
      print threadname, x, count
      time.sleep(1)

if __name__ == '__main__':
  global count, mutex
  threads = []
  num = 4
  count = 1
  # 创建锁
  mutex = threading.Lock()
  # 创建线程对象
  for x in xrange(0, num):
    threads.append(Test(10))
  # 启动线程
  for t in threads:
    t.start()
  # 等待子线程结束
  for t in threads:
    t.join() 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [743]python sqlite3.ProgrammingError: SQLite objects created in a thread can only be used

    引言: SQLite是基于文件系统的mini数据库,我们用以存放简便的数据,本文将描述在代码中碰到的并发问题。

    周小董
  • linux 安装RabbitMQ

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    周小董
  • RuntimeError: An attempt has been made to start a new process before the current process has

    参考:https://blog.csdn.net/jacke121/article/details/81456842

    周小董
  • Python多线程学习

    1、  函数式:调用thread模块中的start_new_thread()函数来产生新线程。如下例:

    流柯
  • Java 四种线程池的用法分析

    Java 四种线程池的用法分析 1、new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnab...

    用户1289394
  • 死磕 java并发包之AtomicStampedReference源码分析

    AtomicStampedReference是java并发包下提供的一个原子类,它能解决其它原子类无法解决的ABA问题。

    彤哥
  • Java并发编程与高并发之线程安全性(原子性、可见性、有序性)

    1、并发的基本概念:同时拥有两个或者多个线程,如果程序在单核处理器上运行,多个线程将交替地换入或者换出内存,这些线程是同时存在的,每个线程都处于执行过程中的某个...

    别先生
  • 【连载】两百行Rust代码解析绿色线程原理(四)一个绿色线程的实现

    在我们开始之前,我得提醒你我们编写的代码非常不安全,并且这也不是编写 Rust 代码的 “最佳实践”。我希望在不引入很多不必要的复杂性的前提下使其尽可能安全,所...

    MikeLoveRust
  • 搜狗号上线,趣头条崛起,搜索引擎与头条们上演生死对决

    北京时间9月14日晚,“拼多多版今日头条”趣头条在纳斯达克上市,首日股价大涨128.14%,盘中一度涨190%,5次触发熔断机制中止交易,市值高达45.88美元...

    罗超频道
  • Dubbo的两种常规启动方式

    然后打成jar给dubbo-user-provider和dubbo-user-consumer使用

    田维常

扫码关注云+社区

领取腾讯云代金券