多线程
 
基本实现:
第一种,函数方式
# -*- 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. C运算符

    运算符是一种告诉编译器执行特定的数学或逻辑操作的符号. C 语言内置了丰富的运算符,并提供了以下类型的运算符: 算术运算符.关系运算符.逻辑运算符.位运算符.赋值运算符.杂项运算符 C 中的运算符优先 ...

  2. Rsync未授权访问漏洞的修复

    转自:https://www.cnblogs.com/KevinGeorge/p/9648028.html 配置文件/etc/rsync.conf解析: motd file -> motd文件位 ...

  3. ----constructor 与 object----

    CONSTRUCTOR constructor是一种特殊的object,同样是用来创建和声明一个类 语法规则: constructor([arguments]) { ... } 注意: 1.在类中,只 ...

  4. Python从入门到精通之Forth!

    Python基本数据类型之列表 补充:range()方法 python2: range   立即创建 xrange  for循环的时候才一个一个创建 Python3: range     for循环的 ...

  5. 语音端点检测(Voice Activity Detection,VAD)

    本文内容均翻译自这篇博文:(该博主的相关文章都比较好,感兴趣的可以自行学习) Voice Activity Detection(VAD) Tutorial 语音端点检测一般用于鉴别音频信号当中的语音出 ...

  6. eclipse遇到启动报an error has occurred see the log file错

    错误: 修改eclipse安装目录下比如D:\eclipse\configuration\.settings\org.eclipse.ui.ide.prefs, 删除 RECENT_WORKSPACE ...

  7. consul搭建

    1.准备3台服务器 linux1 192.168.0.101 linux2 192.168.0.102 linux3 192.168.0.103 2.准备向Linux上传文件的工具Winscp 3.去 ...

  8. 更适用于JavaScript的设计模式:面向委托的设计,了解一下?(下)

    先来看一下传统的面向类式的写法: function Foo(name) { this.name = name; } Foo.prototype.sayName = function() { conso ...

  9. CentOS下安装Git

    在终端输入命令:yum install git,此时会进行提示安装,输入y, 在这种安装方式下,速度很快(windows系统下下载客户端速度超慢),当出现安装完毕时,就可以了. 安装完毕后输入git ...

  10. ASCII、Unicode、UTF-8以及Python3编码问题

    编码问题,其实的确是个很烦人的问题,一开始觉得不需要看,到后来出现问题,真的是抓狂, 而像我们这些刚刚涉及到这些问题的小白来说,更是无从下手,所以查阅资料,总结理解下各个概念以及Python3的编码问 ...