多线程
 
基本实现:
第一种,函数方式
# -*- coding:utf-8 -*-
import thread
import time
 
 
def print_time(threadName, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print '%s : %s' % (threadName, time.ctime(time.time()))
 
 
try:
    thread.start_new_thread(print_time, ("Thread-1", 2,))
    thread.start_new_thread(print_time, ("Thread-2", 4,))
except:
    print "Error!Unable to start thread."
 
while 1:
    pass
 
第二种,继承父类
# -*- coding:utf-8 -*-
import threading
import time
 
 
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 "Starting:" + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting:" + 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()
 
线程同步的问题解决:锁
这里第一个线程执行的时候,第二个线程是等待状态的
# -*- coding:utf-8 -*-
import threading
import time
 
threadLock = threading.Lock()
threads = []
 
 
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 "Starting:" + self.name
        threadLock.acquire()
        print_time(self.name, self.counter, 5)
        print "Exiting:" + self.name
        threadLock.release()
 
 
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, "Thread2", 2)
 
thread1.start()
thread2.start()
 
threads.append(thread1)
threads.append(thread2)
 
for thread in threads:
    thread.join()
 
线程优先级队列:
虽然开启了多个线程,不过打印顺序一定是:one按顺序到five
# -*- coding:utf-8 -*-
import threading
import time
import Queue
 
exit_flag = 0
queue_lock = threading.Lock()
work_queue = Queue.Queue(10)
thread_list = ["Thread-1", "Thread-2", "Thread-3"]
name_list = ["one", "two", "three", "four", "five"]
threads = []
thread_id = 1
 
 
class MyThread(threading.Thread):
    def __init__(self, thread__id, name, queue):
        threading.Thread.__init__(self)
        self.thread__id = thread__id
        self.name = name
        self.queue = queue
 
    def run(self):
        print "Starting:" + self.name
        process_data(self.name, self.queue)
        print "Exiting:" + self.name
 
 
def process_data(thread_name, queue):
    while not exit_flag:
        queue_lock.acquire()
        if not work_queue.empty():
            data = queue.get()
            queue_lock.release()
            print "%s processing %s" % (thread_name, data)
        else:
            queue_lock.release()
        time.sleep(2)
 
 
for t in thread_list:
    thread = MyThread(thread_id, t, work_queue)
    thread.start()
    threads.append(thread)
    thread_id += 1
 
queue_lock.acquire()
for word in name_list:
    work_queue.put(word)
queue_lock.release()
 
while not work_queue.empty():
    pass
 
exit_flag = 1
 
for t in threads:
    t.join()
 
这里的join函数重点解释下:
join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞主线程直到其他线程结束,如果结束则跳转执行下一个线程的join函数
 
接下来看看多线程实际的案例:
多线程访问网站
# -*- coding:utf-8 -*-
import urllib2
import time
from threading import Thread
 
 
class GetUrlThread(Thread):
    def __init__(self, url):
        Thread.__init__(self)
        self.url = url
 
    def run(self):
        response = urllib2.urlopen(self.url)
        print self.url, response.getcode()
 
 
def get_responses():
    urls = [
        'https://www.baidu.com',
        'https://www.taobao.com',
        'https://www.cnblogs.com',
        'https://github.com',
        'https://www.jd.com'
    ]
    start = time.time()
    threads = []
    for url in urls:
        thread = GetUrlThread(url)
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "Time: % s" % (time.time() - start)
 
 
get_responses()
 
如果多个线程访问同一个变量,容易出问题,比如下面:
有可能最后的实际值并不是50
# -*- coding:utf-8 -*-
from threading import Thread
 
some_var = 0
 
 
class IncrementThread(Thread):
    def run(self):
        global some_var
        read_value = some_var
        print "线程%s中的some_var是%d" % (self.name, read_value)
        some_var = read_value + 1
        print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
 
 
def use_increment_thread():
    threads = []
    for i in range(50):
        thread = IncrementThread()
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "在50次运算后some_var应该变成50"
    print "在50次运算后some_var实际值为:%d" % (some_var,)
 
 
use_increment_thread()
 
解决办法,加入一个锁:
这种情况,最后的实际值一定是50
# -*- coding:utf-8 -*-
from threading import Thread, Lock
 
lock = Lock()
some_var = 0
 
 
class IncrementThread(Thread):
    def run(self):
        global some_var
        lock.acquire()
        read_value = some_var
        print "线程%s中的some_var是%d" % (self.name, read_value)
        some_var = read_value + 1
        print "线程%s中的some_var增加后变成%d" % (self.name, some_var)
        lock.release()
 
 
def use_increment_thread():
    threads = []
    for i in range(50):
        thread = IncrementThread()
        threads.append(thread)
        thread.start()
 
    for thread in threads:
        thread.join()
 
    print "在50次运算后some_var应该变成50"
    print "在50次运算后some_var实际值为:%d" % (some_var,)
 
 
use_increment_thread()
 
另一个锁的案例:
不加锁容易出事
# -*- coding:utf-8 -*-
from threading import Thread
import time
 
 
class CreateListThread(Thread):
    def __init__(self):
        self.entries = []
        Thread.__init__(self)
 
    def run(self):
        self.entries = []
        for i in range(10):
            time.sleep(1)
            self.entries.append(i)
        print self.entries
 
 
def use_create_list_thread():
    for i in range(3):
        t = CreateListThread()
        t.start()
 
 
use_create_list_thread()
结果:
[[[000, , , 111, , , 222, , , 333, , , 444, , , 555, , , 666, , , 777, , , 888, , , 999]]]
 
给他加上锁:
# -*- coding:utf-8 -*-
from threading import Thread, Lock
import time
 
lock = Lock()
 
 
class CreateListThread(Thread):
    def __init__(self):
        self.entries = []
        Thread.__init__(self)
 
    def run(self):
        self.entries = []
        for i in range(10):
            time.sleep(1)
            self.entries.append(i)
        lock.acquire()
        print self.entries
        lock.release()
 
 
def use_create_list_thread():
    for i in range(3):
        t = CreateListThread()
        t.start()
 
 
use_create_list_thread()
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python多线程使用和注意事项的更多相关文章

  1. python多线程与_thread模块

    进程与线程 1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件.只有把他们加载到内存中并被操作系统调用,才具有其生命周期.进程则是一个执行中的程序.每个进程都拥有自己的地址空间,内 ...

  2. python多线程学习记录

    1.多线程的创建 import threading t = t.theading.Thread(target, args--) t.SetDeamon(True)//设置为守护进程 t.start() ...

  3. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  4. Python 多线程教程:并发与并行

    转载于: https://my.oschina.net/leejun2005/blog/398826 在批评Python的讨论中,常常说起Python多线程是多么的难用.还有人对 global int ...

  5. python多线程

    python多线程有两种用法,一种是在函数中使用,一种是放在类中使用 1.在函数中使用 定义空的线程列表 threads=[] 创建线程 t=threading.Thread(target=函数名,a ...

  6. python 多线程就这么简单(转)

    多线程和多进程是什么自行google补脑 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂.所以,这里力图用简单的例子,让你对多线程有个初步的认识. 单线程 在好些年前的 ...

  7. python 多线程就这么简单(续)

    之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思.因为我们在使用电脑的过程中无时无刻都在多进程和多线程.我们可以接着之前的例子继续讲.请先看我的上一篇博客. python 多线程就这 ...

  8. python多线程监控指定目录

    import win32file import tempfile import threading import win32con import os dirs=["C:\\WINDOWS\ ...

  9. python多线程ssh爆破

    python多线程ssh爆破 Python 0x01.About 爆弱口令时候写的一个python小脚本,主要功能是实现使用字典多线程爆破ssh,支持ip表导入,字典数据导入. 主要使用到的是pyth ...

随机推荐

  1. centos7 删除swap

    https://www.refmanual.com/2016/01/08/completely-remove-swap-on-ce7/#.W8AaSRMzaRs 删除不干净,启动不起来的情况下.需要从 ...

  2. python json.dumps()函数输出json格式,使用indent参数对json数据格式化输出

    在python中,要输出json格式,需要对json数据进行编码,要用到函数:json.dumps json.dumps() :是对数据进行编码 #coding=gbkimport json dict ...

  3. class 关键字

    class Ninja 表示创建一个名为Ninja的函数.constructor(...)指明Ninja函数的签名和函数体内容. class Ninja{ constructor(name){ thi ...

  4. oracle redo日志文件损坏恢复

    参考:How to Recover from Loss Of Online Redo Log And ORA-312 And ORA-313 (Doc ID 117481.1) 在线重做日志文件丢失后 ...

  5. python 12 模块与包

    一.不知道什么原则 python文件下面只写方法,所有的可直接执行的代码,都放在条件下 原因.该文件有可能被其他文件调用 二.eval() 将字符串转为相应的数据格式可以想象json转为map 三.模 ...

  6. Servlet获取 URL 地址

    使用 ServletRequest 的如下方法 getContextPath 取得项目名 getServletPath 取得Servlet名 getPathInfo 取得Servlet后的URL名,不 ...

  7. gperftools对程序进行分析

    gperftools是google出品的一个性能分析工具,相关介绍可见:https://github.com/gperftools/gperftools/wikigperftools性能分析通过抽样方 ...

  8. java GUI的效果图

    import java.awt.*;import javax.swing.*; public class GridBagDemo extends JFrame {    public static v ...

  9. C#学习笔记14——TRACE、DEBUG和TRACESOURCE的使用以及日志设计

    Trace.Debug和TraceSource的使用以及日志设计   .NET Framework 命名空间 System.Diagnostics 包含用于跟踪执行流程的 Trace.Debug 和 ...

  10. 2019-1-18 Spark 机器学习

    2019-1-18 Spark 机器学习 机器学习 模MLib板 预测 //有视频 后续会补充 1547822490122.jpg 1547822525716.jpg 1547822330358.jp ...