线程
线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
python线程的模块:
- _thread
- threading
thread模块
_thread创建多线程: _thread.start_new_thread(线程需要执行的任务(任务需要的参数, 元组数据类型 ))
import _thread
import time
def job(name):
print("这是一个需要执行的任务")
print(name, time.ctime())
time.sleep(2)
if __name__ == "__main__":
# 创建多个线程, 但是没有开始执行任务;
_thread.start_new_thread(job,('thread1', ))
_thread.start_new_thread(job,('thread2', ))
while True:
pass
threading模块
import threading
import time
def job(name):
print("这是一个需要执行的任务: %s" %(name))
# 激活的线程个数
print("当前线程的个数:", threading.active_count())
# 打印当前线程的详细信息
print("当前线程信息:", threading.current_thread())
time.sleep(100)
print(name, time.ctime())
if __name__ == "__main__":
job('job0')
# 创建多个线程
t1 = threading.Thread(target=job, name='job1', args=("job1-name",))
t1.start()
t2 = threading.Thread(target=job, name='job2', args=("job2-name",))
t2.start()
print('hello')
join方法
join所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止
import threading
import time
def job():
time.sleep(1)
print('job')
t1 = threading.Thread(target=job)
t1.start()
t1.join() # 会等待, 直到t1线程执行结束;阻塞正在调用的线程
t2 = threading.Thread(target=job)
t2.start()
t2.join() # 会等待, 直到t2线程执行结束;阻塞正在调用的线程
print('main thread end')
守护线程(setdaemon方法)
使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止
# 当主线程执行结束, 让没有执行的线程强制结束;set_daemon
import threading
import time
# 任务1:
def music(name):
for i in range(2):
print("正在听音乐%s" %(name))
time.sleep(1)
# 任务2:
def code(name):
for i in range(2):
print("正在编写代码%s" %(name))
time.sleep(2)
if __name__ == '__main__':
start_time = time.time()
t1 = threading.Thread(target=music, args=("最初的梦想",))
t2 = threading.Thread(target=code, args=("源代码", ))
# 将t1线程生命为守护线程, 如果设置为True, 子线程启动, 当主线程执行结束, 子线程也结束
# 设置setDaemon必须在启动线程之前进行设置;
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()
# 等待所有的子线程执行结束之后, 继续执行主线程的内容;
# t1.join()
# t2.join()
print("花费时间: %s" %(time.time()-start_time))
多线程应用
获取IP地理位置
import json
import threading
from urllib.request import urlopen
import time
def job(ip):
"""获取指定ip对应的地理位置"""
url = "http://ip.taobao.com/service/getIpInfo.php?ip=%s" % (ip)
# 根据url获取网页的内容, 并且解码为utf-8格式, 识别中文;
text = urlopen(url).read().decode('utf-8')
# 将获取的字符串类型转换为字典, 方便处理
d = json.loads(text)['data']
country = d[