关于线程

#线程
1.###创建线程

import  _thread
import  threading
import time
def job():
    print("这是一个需要执行的任务")    
    print("当前线程的个数:", threading.active_count()) #开启线程的个数
    print("当前线程信息:", threading.current_thread()) #线程的详细信息
    time.sleep(100)
if __name__ == "__main__":
    job()

这是一个需要执行的任务
当前线程的个数: 1
当前线程信息: <_MainThread(MainThread, started 140171535042368)>

2.###创建多线程

import _thread
import threading
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
这是一个需要执行的任务
thread1 Thu Sep 20 21:47:05 2018
这是一个需要执行的任务
thread2 Thu Sep 20 21:47:05 2018

3.###threading模块中通过实例化对象创建多线程

import _thread
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",))#target=后接调用函数名,args=连接函数中的参数,name=更改线程的名字  (若函数中只有一个参数,args后括号内的值后面跟',',因为是元组)
    t1.start()
    t2 = threading.Thread(target=job, name='job2', args=("job2-name",))
    t2.start()
这是一个需要执行的任务: job0
当前线程的个数: 1
当前线程信息: <_MainThread(MainThread, started 139794205583168)>
job0 Thu Sep 20 22:04:35 2018
这是一个需要执行的任务: job1-name
当前线程的个数: 2
当前线程信息: <Thread(job1, started 139794079086336)>
这是一个需要执行的任务: job2-name
当前线程的个数: 3
当前线程信息: <Thread(job2, started 139794070693632)>
job1-name Thu Sep 20 22:04:37 2018
job2-name Thu Sep 20 22:04:37 2018

4.###关于join
####join方法: 会等待, 直到运行中的线程执行结束;阻塞正在调用的线程

import  threading
import time
def job():
    time.sleep(5)
    print('job')
t1 = threading.Thread(target=job)
t1.start()
t1.join()  # 会等待, 直到t1线程执行结束;阻塞正在调用的线程
t2 = threading.Thread(target=job)
t2.start()
t2.join()   # 会等待, 直到t2线程执行结束;阻塞正在调用的线程

####join的应用

import threading
import time
def music(name):
    for i in range(2):
        print("正在听%s" %(name))
        time.sleep(1)
def code(name):
    for i in range(2):
        print("正在写%s" %(name))
        time.sleep(2)
if __name__ == '__main__':    
    t1 = threading.Thread(target=music, args=("好运来",))
    t1.start()
    t1.join()#等待t1执行完
    t2 = threading.Thread(target=code, args=("爬虫", ))
    t2.start()
    t2.join()#等待t2执行完成

5.###set_daemon方法
####它的作用是当主线程执行结束时,让没有执行的线程强制结束,即将线程声明为守护线程–set_daemon(True)

import threading
import time
def music(name):
    for i in range(2):
        print("正在听%s" %(name))
        time.sleep(1)
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, 子线程启动, 当主线程执行结束, 子线程也结束
    # 设置set_Daemon必须在启动线程之前进行设置;
    t1.setDaemon(True)
    t2.setDaemon(True)
    t1.start()
    t2.start()
    print("花费时间: %s" %(time.time()-start_time))
正在听音乐好运来
正在编写代码爬虫
花费时间: 0.00017547607421875

6.###多线程应用:获取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['country']
    city = d['city']
    print("%s:" %(ip), country, city)
def has_many_thread():
    start_time = time.time()
    threads = []
    ips = ['172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8' ]
    for ip in ips:
        # 实例化线程对象
        t = threading.Thread(target=job, args=(ip, ))
        threads.append(t)
        # 启动线程执行任务
        t.start()
    # join方法
    [thread.join() for thread in threads]
    print("Success, 使用多线程运行时间为:%s" %(time.time()-start_time))
def has_no_thread():
    start_time = time.time()
    ips = ['172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8',
           '172.25.254.250', '8.8.8.8']
    for ip in ips:
        job(ip)
    print("Success, 未使用多线程运行时间为:%s" % (time.time() - start_time))
if __name__ == '__main__':
    has_many_thread()
    has_no_thread()

7.###通过继承方式创建线程

import  threading
class Thread(threading.Thread):
    def __init__(self, jobname):
        super(IpThread, self).__init__()#声明为父类函数
        self.jobname = jobname
    def run(self):    # 将多线程需要执行的任务重写到run方法中;
        print("this is  a job")

t1 = IpThread(jobname="new job")
t1.start()

8.###线程锁:因为多线程是中的各个线程是同时工作运行的,所以当对其中某个线程中的数据作出改动时,会出现未知的错误,此时就需要线程锁来控制被修改数据
####用以下例子来说明线程锁的作用
#####不用线程锁

import threading
def add(lock):
    global money
    for i in range(1000000):
        money+=1
def reduce(lock):
    global money
    for i in range(1000000):
        money-=1
if __name__=='__main__':
    money=0
    lock=threading.Lock()
    t1=threading.Thread(target=add,args=(lock,))
    t2=threading.Thread(target=reduce,args=(lock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("最终金额为:%s"%(money))
最终金额为:452364   # 结果本应该是零,因为没有线程锁,会出现错误

#####使用线程锁

import threading
def add(lock):
    lock.acquire()#上锁
    global money
    for i in range(10000):
        money+=1
    lock.release()#释放
def reduce(lock):
    lock.acquire()
    global money
    for i in range(10000):
        money-=1
    lock.release()
if __name__=='__main__':
    money=0
    lock=threading.Lock()
    t1=threading.Thread(target=add,args=(lock,))
    t2=threading.Thread(target=reduce,args=(lock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("最终金额为:%s"%(money))
最终金额为:0  #结果始终为0

9.###队列与多线程
####因为多线程在执行后会产生数据,但它并不能返回任务执行结果,可以用队列来存储多线程产生的数据

import threading
from collections import Iterable
from mytimeit import timeit
from queue import  Queue
def job(l, queue):
    # 将任务的结果存储到队列中;
    queue.put(sum(l))
@timeit
def use_thread():
    # 实例化一个队列, 用来存储每个线程执行的结果;
    q = Queue()
    # # 入队
    # q.put(1)
    li = [[1,2,3,4,5], [2,3,4,5,6], [2,3,4,5,6,7,8], [2,3,4,5,6]]
    threads = []
    for i in li:
        t = threading.Thread(target=job, args=(i, q))
        threads.append(t)
        t.start()
    # join方法等待所有子线程之心结束
    [thread.join() for thread in threads]
    # 从队列里面拿出所有的运行结果
    result = [q.get() for _ in li]
    print(result)
    # print(isinstance(q, Iterable))
if __name__ == "__main__":
    use_thread()
[15, 20, 35, 20]
use_thread执行时间0.0006349086761474609

10.###线程池:存放多个线程单位,同时有着对应的任务队列,在执行过程中就是使用线程池中已有的有限线程作完任务,它的好处就是不必对每一个任务都创建一个线程,节省了工作时间,减少了工作量(python3.2之后才可以使用)

def job():
    print("this is a job")
    return  "hello"
if __name__ == '__main__':
    pool = ThreadPoolExecutor(max_workers=10)# 实例化对象, 线程池包含10个线程来处理任务;
    # 往线程池里面扔需要执行的任务, 返回一个对象,( _base.Future实例化出来的)
    f1 = pool.submit(job)
    f2 = pool.submit(job)
    # 判断任务是否执行结束
    print(f1.done())
    time.sleep(1)
    print(f2.done())
    # 获取任务执行的结果
    print(f1.result())
    print(f2.result())

11.###线程池与map函数


from urllib.error import HTTPError
from urllib.request import urlopen
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
import time
URLS = ['http://httpbin.org', 'http://example.com/',
        'https://api.github.com/'] * 10
def get_page(url, timeout=3):
    try:
        content = urlopen(url).read()
        return {'url':url, 'len':len(content)}
    except HTTPError as e:
        return {'url':url, 'len':0}
pool = ThreadPoolExecutor(max_workers=20)
for res in pool.map(get_page, URLS):
    print(res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值