多线程 threading模块 学习笔记_[threading

47 阅读7分钟

多线程

线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。

threading

启动一个线程就是把一个函数传入并创建threading.Thread( )实例,然后调用start( )开始执行:

实例:

import threading #导入线程模块
import time

#线程函数
def foo(num):
    print('我的进程名字为:'+threading.current_thread().name)
    time.sleep(2)
    print(num)

#创建进程  #callback:回调函数 一般用来接收子进程运行函数的返回值
t1 = threading.Thread(target=foo,args=(1,),callback=func)
t2 = threading.Thread(target=foo,args=(2,))

#启动线程
t1.start()
t2.start()

#获取线程运行状态 True为运行 False为未运行
print(t1.is_alive())
print(t2.is_alive())

#等待所有线程运行完毕在继续往下执行
t1.join()
t2.join()

执行结果为:

我的进程名字为:Thread-1
我的进程名字为:Thread-2
True   #运行状态
True   #运行状态
1      #第一个线程打印
2      #第二个线程打印
  • threading.current_thread( ) 它返回当前线程的实例
  • join( )在子线程执行完成之前,这个子线程的父线程将一直被阻塞。就是说,当调用join()的子进程没有结束之前,主进程不会往下执行。对其它子进程没有影响。
  • is_alive() 获取线程的运行状态
守护进程setDaemon(True)

将线程声明为守护线程,必须在start() 方法调用之前设置, 如果不设置为守护线程程序会被无限挂起。这个方法基本和join是相反的。当我们 在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程 就兵分两路,分别运行,那么当主线程完成想退出时,会检验子线程是否完成。如 果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是 只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以用setDaemon方法。

实例:

import threading
from time import ctime,sleep
import time

def music(func):
    for i in range(2):
        print ("Begin listening to %s. %s" %(func,ctime()))
        sleep(4)
        print("end listening %s"%ctime())

def move(func):
    for i in range(2):
        print ("Begin watching at the %s! %s" %(func,ctime()))
        sleep(5)
        print('end watching %s'%ctime())

threads = []
t1 = threading.Thread(target=music,args=('七里香',))
threads.append(t1)
t2 = threading.Thread(target=move,args=('阿甘正传',))
threads.append(t2)

if __name__ == '__main__':

    for t in threads:
        t.setDaemon(True)
        t.start()


    print ("all over %s" %ctime())

执行结果为:

Begin listening to 七里香. Thu Sep 29 15:45:32 2016    #t1和t2启动,分别打印一次后sleep,主进程继续
Begin watching at the 阿甘正传! Thu Sep 29 15:45:32 2016
all over Thu Sep 29 15:45:32 2016              #主进程结束,程序结束
Lock互斥锁

多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

实例:

import threading

num = 0
def add():
    global  num
    for  i in range(1000000):
            num += 1

t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)

t1.start()
t2.start()

t1.join()
t2.join()

print(num)

运行结果为:

1183554

为什么会出现这样的问题呢 上面已经说过了,线程间任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。这种情况要使用lock (互斥锁)

实例:

import threading

num = 0
def add():
    global  num
    for  i in range(1000000):
        lock.acquire()#上锁
        num += 1
        lock.release()#解锁
        #也可以使用with方法效果相同
        # with lock:
        #     num += 1

t1 = threading.Thread(target=add)
t2 = threading.Thread(target=add)
#创建互斥锁 只能有一个进程同时访问
lock = threading.Lock()
t1.start()
t2.start()

t1.join()
t2.join()

print(num)

运行结果为:

2000000
信号量

信号量是允许同一时间同时几个线程访问共享变量

import threading,time

def foo(i):
    # 上锁
    sem.acquire()
    time.sleep(1)
    print(i)
    # 解锁
    sem.release()

# 锁 --- 信号量
sem = threading.BoundedSemaphore(3)

for i in range(10):
    t = threading.Thread(target=foo,args=(i,))
    t.start()

自己体验执行结果会更容易理解信号量

Event(事件)

小伙伴a,b,c围着吃火锅,当菜上齐了,请客的主人说:开吃!,于是小伙伴一起动筷子,这种场景如何实现?

Event(事件):事件处理的机制:全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么event.wait 方法时便不再阻塞。Event没有锁,无法使线程进入同步阻塞状态。
set(): 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态。

clear(): 将标志设为False。

wait(timeout): 如果标志为True将立即返回,否则阻塞线程至等待阻塞状态,等待其他线程调用set()。

isSet(): 获取内置标志状态,返回True或False。

import threading
import time

event = threading.Event()

def chihuoguo(name):
    # 等待事件,进入等待阻塞状态
    print '%s 已经启动' % threading.currentThread().getName()
    print '小伙伴 %s 已经进入就餐状态!'%name
    time.sleep(1)
    event.wait()
    # 收到事件后进入运行状态
    print '%s 收到通知了.' % threading.currentThread().getName()
    print '小伙伴 %s 开始吃咯!'%name

# 设置线程组
threads = []

# 创建新线程
thread1 = threading.Thread(target=chihuoguo, args=("a", ))
thread2 = threading.Thread(target=chihuoguo, args=("b", ))

# 添加到线程组
threads.append(thread1)
threads.append(thread2)

# 开启线程
for thread in threads:
    thread.start()

time.sleep(0.1)
# 发送事件通知
print '主线程通知小伙伴开吃咯!'
event.set()

运行结果:

Thread-1 已经启动
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!



### 一、Python所有方向的学习路线



Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。



![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d373aa70917b40e1baa9097db71b3807~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=mMu7byYuFlv1%2F7Bmnjh16Ut8sTA%3D)



### 二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。



![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cc957ba506e54430bddd1aa8d6b1df83~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=h24pfFPkRwIZp09GXGDugSH36r4%3D)



### 三、全套PDF电子书



书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/1215855d49154542801840c4158ffccf~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=UE%2FUrElFE%2FWQQShv33PnXfK7fvU%3D)



### 四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。



![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/aea3e0188bef4161883326239178fbdb~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=PpbnnLiTfrvMKEgPK5KU9scGpL0%3D)



### 五、实战案例



光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。



![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cae077c82a71471bb4ae2e5cb7fe57f1~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=Muxp14koKTTprJmFDszyAuq3Ka0%3D)



### 六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。



![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3c1b87b6d86646a6bbdb6253affd73d4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=Noxn21%2BuumR31xIz05S%2Be3ueV8c%3D)  

![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/bf5344f168294c89a846aeb24f9e0974~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3NTc5MjMwMTY3MDI=:q75.awebp?rk3s=f64ab15b&x-expires=1771415500&x-signature=YzaXR%2FW2YjMBjED5crlMWm0%2FEt8%3D)



**了解详情:https://docs.qq.com/doc/DSnl3ZGlhT1RDaVhV**