关于线程

#线程
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)

### 回答1: 下面是一个关于创建线程的 Python 代码示例: ``` import threading class MyThread(threading.Thread): def __init__(self, thread_id, name, counter): threading.Thread.__init__(self) self.thread_id = thread_id self.name = name self.counter = counter def run(self): print("开始线程:" + self.name) print_time(self.name, self.counter, 5) print("退出线程:" + self.name) def print_time(thread_name, delay, counter): while counter: time.sleep(delay) print("%s: %s" % (thread_name, time.ctime(time.time()))) counter -= 1 thread1 = MyThread(1, "Thread-1", 1) thread2 = MyThread(2, "Thread-2", 2) thread1.start() thread2.start() thread1.join() thread2.join() print("退出主线程") ``` 在这段代码中,我们定义了一个 `MyThread` 类,继承自 Python 中的 `threading.Thread` 类。在这个类中,我们重写了 `run` 方法,来执行线程的任务。接着,我们创建了两个线程对象,并启动它们。最后,使用 `join` 方法等待两个线程执行完毕。 ### 回答2: 在Python中,可以使用`threading`模块来创建和管理线程。下面是一个简单的示例代码,使用Python的类来实现线程: ```python import threading import time class MyThread(threading.Thread): def __init__(self, name): threading.Thread.__init__(self) self.name = name def run(self): print(f"线程 {self.name} 启动") # 执行线程任务 for i in range(5): print(f"线程 {self.name}: 执行任务 {i}") time.sleep(1) print(f"线程 {self.name} 结束") # 创建两个线程对象 thread1 = MyThread("线程1") thread2 = MyThread("线程2") # 启动线程 thread1.start() thread2.start() # 等待线程完成 thread1.join() thread2.join() print("主线程结束") ``` 这个示例代码定义了一个`MyThread`类,继承自`threading.Thread`类,重写了`run`方法,该方法是线程的入口点。在`run`方法中,我们定义了线程要执行的任务。 然后,我们创建了两个`MyThread`对象,分别命名为"线程1"和"线程2"。接着,我们分别启动这两个线程,并使用`join`方法等待线程执行完毕。 最后,主线程打印出 "主线程结束",表示主线程的执行也结束了。 这段代码演示了如何使用Python的类来创建和管理线程。每个线程执行自己的任务,而不会干扰其他线程的执行。使用类可以方便地管理线程,并提供更好的代码组织和可维护性。 ### 回答3: 下面是一个使用Python类编写的关于线程的代码示例: ```python import threading import time # 创建一个继承自Thread类的自定义线程类 class MyThread(threading.Thread): def __init__(self, thread_id, name): threading.Thread.__init__(self) self.thread_id = thread_id self.name = name # 重写run方法,线程启动后执行该方法 def run(self): print("线程 " + self.name + " 正在运行...") time.sleep(2) # 线程休眠2秒 print("线程 " + self.name + " 运行结束.") # 创建线程对象 thread1 = MyThread(1, "Thread 1") thread2 = MyThread(2, "Thread 2") # 启动线程 thread1.start() thread2.start() # 等待线程执行完毕 thread1.join() thread2.join() print("所有线程执行完毕.") ``` 以上代码定义了一个自定义的线程类`MyThread`,该类继承自`Thread`类,并重写了`run`方法,用于线程的实际操作。在`run`方法中,我们模拟了线程运行2秒的操作。然后,创建了两个线程对象`thread1`和`thread2`,并通过调用`start`方法启动它们。最后,调用`join`方法等待线程执行完毕,并输出"所有线程执行完毕"的提示。 这段代码展示了如何使用Python的类编写多线程程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值