python笔记1--线程

线程:thread
    线程也是多任务编程的一种方法,可以使用计算机多核资源。
    线程是计算机核心分配的最小单位
    线程又称为轻量级进程,在创建和删除时消耗的计算机资源少

线程和进程关系:
1, 一个进程中可以包含多个线程
2, 进程中的所有线程共享进程的空间资源。(空间、全局变量、分配的内存等)
3, 如果一个进程里面只有一个线程,即单线程情况下,线程和进程等同
4, 线程也有自己的特有属性:指令集,TID等,没有终端命令查看
    

线程模块:threading
import threading


t = Thread()
功能:创建线程
参数:target    线程函数
      args        元祖, 给线程函数位置传参
      kwargs    字典,给线程函数字典传参
      name        给线程取名字(默认Thread-1)
返回: 线程对象

t.start()    启动线程
t.join()    回收线程
t.is_alive()查看线程状态
t.name        查看线程名称
t.setName('thread_name') 为线程设置名称
threading.currentThread()得到线程对象

t.daemon:
    默认false, 主线程执行完毕,不会影响分支线程的执行;
    如果设置为True,则主线程执行完毕,其他线程也会终止
    
t.isDaemon():    
    判断daemon属性是True还是False
    
设置daemon方法:
    t.daemon = True 或者
    t.setDaemon(True)

      
      
eg: 线程创建案例
 


#!/usr/bin/python
#coding:utf-8

import threading
from time import sleep

#定义函数,用于循环打印
def play_music():
	while True:
		sleep(2)
		print('一剪梅.mp3')
		
#创建线程
t1 = threading.Thread(target = play_music)

#启动线程
t1.start()

#主线程
while True:
	sleep(2)
	print('梁静茹.wav')

t1.join()

eg2: 测试线程方法
 


#!/usr/bin/python
#coding:utf-8

import threading
from time import sleep

#自定义函数,打印线程名称,睡眠sec秒
def thread_info(sec):
	print('thread attribute testing',threading.currentThread().getName())
	sleep(sec)
	print('thread end.',threading.currentThread().getName())
	
#循环创建线程
thread_lst = []
for i in range(4):
	t = threading.Thread(name='thread'+str(i), target = thread_info, args = (3,))
	t.start()
	thread_lst.append(t)

#循环回收线程,且打印状态
for i in thread_lst:
	print('name:',i.name,'alive:',i.is_alive())
	i.join()

print('father process end....')

eg3: 测试daemon
 

#!/usr/bin/python
#coding:utf-8
import threading
from time import sleep


print('主线程开始')

#自定义函数
def play():
	for _ in range(5):
		print('我是子线程', threading.currentThread().getName())
		sleep(3)

#创建子线程
t = threading.Thread(target = play, name = 'thread_testing')

#设置t.daemon属性为True,设置为true后,主线程结束,则子线程结束
print('thread daemon status:',t.isDaemon())
t.setDaemon(True)
print('thread daemon status:',t.isDaemon())

t.start()
t.join(2)


#此时主线程结束,观察子线程状态
print('主线程结束')

线程间通信

因为线程是共享全局变量和内存,所以可以通过全局变量进行通信
 

#!/usr/bin/python
#coding:utf-8
import threading
from time import sleep


global a
def fun_t1():
	for _ in range(5):
		sleep(1)
		a = 100
		print('a = ',a)
	
def fun_t2():
	for _ in range(5):
		sleep(1.1)
		a = 200
		print('a = ',a)
	
t1 = threading.Thread(target = fun_t1,name = 'thread1')
t2 = threading.Thread(target = fun_t2,name = 'thread2')

t1.start()
t2.start()

t1.join()
t2.join()

进程和线程对比


1, 两者都是多任务编程方式,均可使用计算机多核资源
2, 进程的创建和删除比线程消耗更多的资源
3, 进程空间独立,数据安全性更好操作,有专门的进程间通信方式。(磁盘/Socket/管道/队列/共享内存/信号/信号量)
4, 线程使用全局变量通信,往往要和同步互斥机制配合,防止产生资源的争夺
5, 一个进程可以包含多个线程,线程共享进程资源。
6, 进程线程都有自己的特有资源。


使用场景

线程:需要创建较多的并发,但任务比较简单; 
      如果多个业务有关联性,数据资源重叠较多,要考虑到线程锁是否需要更复杂逻辑
      python中,线程不适用计算密集型并发程序
        
进程:多个任务并无关联性;

 

创建自定义线程类
1, 继承Thread类
2, 重写run方法

#!/usr/bin/python
#coding:utf-8
from time import sleep, ctime
from threading import Thread

#自定义函数
def player(filename,sec):
    for _ in range(3):
        sleep(sec)
        print('playing ',filename,'time:',ctime())

#自定义类,继承Thread类
class myThread(Thread):
    def __init__(self,fun,args,name = 'tony'):
        super().__init__()
        self.fun = fun
        self.args = args
        self.name = name
    def run(self):
        self.fun(*self.args)
#创建进程
t = myThread(player, ('我的中国心',3))
t.start()
t.join()    


线程中同步互斥方法:
Event:线程事件
    e = Event()
    e.set()
    e.wait()
    e.clear()
    e.is_set()
Lock: 线程锁
    lock = Lock() 创建线程锁
    lock.acquire() 加锁
    lock.release()    解锁
    with lock....
        pass
        

condition : 条件变量

con = Condition()    创建条件对象
    
con.acquire()    对资源加锁,加锁后,其他资源再次加锁则阻塞
con.release()    对资源解锁,用法同Lock()
con.wait()        wait函数会先解锁(release()),然后让线程处于等待通知的阻塞状态
                wait函数只能在加锁的状态下使用;
con.notify()    发送通知,线程接收到通知后,结束wait阻塞,并且执行acquire()加锁操作
 

#!/usr/bin/python3
#coding:utf-8
import threading
from time import sleep

con = threading.Condition()


#定义增长函数
def Grow():
    global n
    n = 0
    con.acquire()
    for _ in range(15):
        print('千山鸟飞绝,万径人踪灭',n)
        sleep(1)
        n += 1
        #当n>=3的时候,执行notify(),发送通知,让对方结束wait阻塞,并加锁; 自己紧接着执行wait()阻塞;
        if n >= 3:
            con.notify()
            con.wait()
    con.release()


#定义下降函数
def Down():
    global n
    n  = 0
    con.acquire()
    for _ in range(15):
        print('孤舟蓑笠翁,独钓寒江雪',n)
        sleep(1)
        n -= 1
        #当n<=0的时候,发送通知,并阻塞
        if n <= 0:
            con.notify()
            con.wait()
    con.release()


t1 = threading.Thread(target=Grow)
t2 = threading.Thread(target=Down)

t1.start()
t2.start()

t1.join()
t2.join()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值