Python并发编程之线程消息通信机制任务协调(四)

大家好,并发编程 进入第四篇。 本文目录 前言 Event事件 Condition Queue队列 总结 . 前言 前面我已经向大家介绍了,如何使用创建线程,启动线程。相信大家都会有这样一个想法,线程无非就是创建一下,然后再start()下,实在是太简单了。 可是要知道,在真实的项目中,实际场景可要我们举的例子要复杂的多得多,不同线程的执行可能是有顺序的,或者说他们的执行是有条件的,是要受控制的。如果仅仅依靠前面学的那点浅薄的知识,是远远不够的。 那今天,我们就来探讨一下如何控制线程的触发执行。 要实现对多个线程进行控制,其实本质上就是消息通信机制在起作用,利用这个机制发送指令,告诉线程,什么时候可以执行,什么时候不可以执行,执行什么内容。 经过我的总结,线程中通信方法大致有如下三种: threading.Event threading.Condition queue.Queue 先抛出结论,接下来我们来一一探讨下。 . Event事件 Python提供了非常简单的通信机制 Threading.Event,通用的条件变量。多个线程可以等待某个事件的发生,在事件发生后,所有的线程都会被激活。 关于Event的使用也超级简单,就三个函数 event = threading.Event() # 重置event,使得所有该event事件都处于待命状态 event.clear() # 等待接收event的指令,决定是否阻塞程序执行 event.wait() # 发送event指令,使所有设置该event事件的线程执行 event.set() 举个例子来看下。 import time import threading class MyThread(threading.Thread): def __init__(self, name, event): super().__init__() self.name = name self.event = event def […]

Python并发编程之谈谈线程中的“锁机制”(三)

大家好,并发编程 进入第三篇。 今天我们来讲讲,线程里的锁机制。 本文目录 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL(全局锁) 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL(全局锁) . 何为Lock( 锁 )? 何为 Lock( 锁 ),在网上找了很久,也没有找到合适的定义。可能 锁 这个词已经足够直白了,不需要再解释了。 但是,对于新手来说,我还是要说下我的理解。 我自己想了个生活中例子来看下。 有一个奇葩的房东,他家里有两个房间想要出租。这个房东很抠门,家里有两个房间,但却只有一把锁,不想另外花钱是去买另一把锁,也不让租客自己加锁。这样租客只有,先租到的那个人才能分配到锁。X先生,率先租到了房子,并且拿到了锁。而后来者Y先生,由于锁已经已经被X取走了,自己拿不到锁,也不能自己加锁,Y就不愿意了。也就不租了,换作其他人也一样,没有人会租第二个房间,直到X先生退租,把锁还给房东,可以让其他房客来取。第二间房间才能租出去。 换句话说,就是房东同时只能出租一个房间,一但有人租了一个房间,拿走了唯一的锁,就没有人再在租另一间房了。 回到我们的线程中来,有两个线程A和B,A和B里的程序都加了同一个锁对象,当线程A率先执行到lock.acquire()(拿到全局唯一的锁后),线程B只能等到线程A释放锁lock.release()后(归还锁)才能运行lock.acquire()(拿到全局唯一的锁)并执行后面的代码。 这个例子,是不是让你清楚了什么是锁呢? . 如何使用Lock( 锁 )? 来简单看下代码,学习如何加锁,获取钥匙,释放锁。 import threading # 生成锁对象,全局唯一 lock = threading.Lock() # 获取锁。未获取到会阻塞程序,直到获取到锁才会往下执行 lock.acquire() # 释放锁,归回倘,其他人可以拿去用了 lock.release() 需要注意的是,lock.acquire() 和 lock.release()必须成对出现。否则就有可能造成死锁。 很多时候,我们虽然知道,他们必须成对出现,但是还是难免会有忘记的时候。 为了,规避这个问题。我推荐使用使用上下文管理器来加锁。 import threading […]

Python并发编程之创建多线程的几种方法(二)

今天的内容会比较基础,主要是为了让新手也能无障碍地阅读,所以还是要再巩固下基础。学完了基础,你们也就能很顺畅地跟着我的思路理解以后的文章。 本文目录 学会使用函数创建多线程 学会使用类创建多线程 多线程:必学函数讲解 经过总结,Python创建多线程主要有如下两种方法: 函数 类 接下来,我们就来揭开多线程的神秘面纱。 . 学会使用函数创建多线程 在Python3中,Python提供了一个内置模块 threading.Thread,可以很方便地让我们创建多线程。 threading.Thread() 一般接收两个参数: 线程函数名:要放置线程让其后台执行的函数,由我们自已定义,注意不要加(); 线程函数的参数:线程函数名所需的参数,以元组的形式传入。若不需要参数,可以不指定。 举个例子 1import time 2from threading import Thread 3 4# 自定义线程函数。 5def main(name=”Python”): 6 for i in range(2): 7 print(“hello”, name) 8 time.sleep(1) 9 10# 创建线程01,不指定参数 11thread_01 = Thread(target=main) 12# 启动线程01 13thread_01.start() 14 15 16# 创建线程02,指定参数,注意逗号 17thread_02 = Thread(target=main, […]

盘点 Python 中的那些冷知识(一)

小明在日常Code中遇到一些好玩,冷门的事情,通常都会记录下来。 现在已经积攒了一些了,最近打算整理一波,发出来给大家补补。一篇只分享五个,有时间了就整理。不想错过的,千万记得关注一下。 1. 省略号也是对象 … 这是省略号,在Python中,一切皆对象。它也不例外。 在 Python 中,它叫做 Ellipsis 。 在 Python 3 中你可以直接写…来得到这玩意。 >>> … Ellipsis >>> type(…) <class ‘ellipsis’> 而在 2 中没有…这个语法,只能直接写Ellipsis来获取。 >>> Ellipsis Ellipsis >>> type(Ellipsis) <type ‘ellipsis’> >>> 它转为布尔值时为真 >>> bool(…) True 最后,这东西是一个单例。 >>> id(…) 4362672336 >>> id(…) 4362672336 这东西有啥用呢?据说它是Numpy的语法糖,不玩 Numpy 的人,可以说是没啥用的。 在网上只看到这个 用 … 代替 pass ,稍微有点用,但又不是必须使用的。 try:     1/0 except ZeroDivisionError:     … 2. 类首字母不一定是大写 在正常情况下,我们所编写的所见到的代码,好像都默许了类名首字母大写,而实例用小写的这一准则。但这并不是强制性的,即使你反过来的也没有关系。 但有一些内置的类,首字母都是小写,而实例都是大写。 比如 bool 是类名,而 […]

Python并发编程之深入理解yield from语法(八)

大家好,并发编程 进入第八篇。 直到上一篇,我们终于迎来了Python并发编程中,最高级、最重要、当然也是最难的知识点–协程。 当你看到这一篇的时候,请确保你对生成器的知识,有一定的了解。当然不了解,也没有关系,你只要花个几分钟的时间,来看下我上一篇文章,就能够让你认识生成器,入门协程了。 再次提醒: 本系列所有的代码均在Python3下编写,也建议大家尽快投入到Python3的怀抱中来。 本文目录 为什么要使用协程 yield from的用法详解 为什么要使用yield from . 为什么要使用协程 在上一篇中,我们从生成器的基本认识与使用,成功过渡到了协程。 但一定有许多人,只知道协程是个什么东西,但并不知道为什么要用协程?换句话来说,并不知道在什么情况下用协程? 它相比多线程来说,有哪些过人之处呢? 在开始讲yield from 之前,我想先解决一下这个给很多人带来困惑的问题。 举个例子。 假如我们做一个爬虫。我们要爬取多个网页,这里简单举例两个网页(两个spider函数),获取HTML(耗IO耗时),然后再对HTML对行解析取得我们感兴趣的数据。 我们的代码结构精简如下: def spider_01(url): html = get_html(url) … data = parse_html(html) def spider_02(url): html = get_html(url) … data = parse_html(html) 我们都知道,get_html()等待返回网页是非常耗IO的,一个网页还好,如果我们爬取的网页数据极其庞大,这个等待时间就非常惊人,是极大的浪费。 聪明的程序员,当然会想如果能在get_html()这里暂停一下,不用傻乎乎地去等待网页返回,而是去做别的事。等过段时间再回过头来到刚刚暂停的地方,接收返回的html内容,然后还可以接下去解析parse_html(html)。 利用常规的方法,几乎是没办法实现如上我们想要的效果的。所以Python想得很周到,从语言本身给我们实现了这样的功能,这就是yield语法。可以实现在某一函数中暂停的效果。 试着思考一下,假如没有协程,我们要写一个并发程序。可能有以下问题 1)使用最常规的同步编程要实现异步并发效果并不理想,或者难度极高。 2)由于GIL锁的存在,多线程的运行需要频繁的加锁解锁,切换线程,这极大地降低了并发性能; 而协程的出现,刚好可以解决以上的问题。它的特点有 协程是在单线程里实现任务的切换的 利用同步的方式去实现异步 不再需要锁,提高了并发性能 . yield from的用法详解 yield […]

怎么给字符串字段加索引?

现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题。 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的: mysql> create table SUser( ID bigint unsigned primary key, email varchar(64), … )engine=innodb; 由于要使用邮箱登录,所以业务代码中一定会出现类似于这样的语句: mysql> select f1, f2 from SUser where email=’xxx’; 从第 4 和第 5 篇讲解索引的文章中,我们可以知道,如果 email 这个字段上没有索引,那么这个语句就只能做全表扫描。 同时,MySQL 是支持前缀索引的,也就是说,你可以定义字符串的一部分作为索引。默认地,如果你创建索引的语句不指定前缀长度,那么索引就会包含整个字符串。 比如,这两个在 email 字段上创建索引的语句: mysql> alter table SUser add index index1(email); 或 mysql> alter table SUser add index index2(email(6)); 第一个语句创建的 index1 索引里面,包含了每个记录的整个字符串;而第二个语句创建的 index2 […]

mac 安装Nginx

WHAT 本篇主要是基于Nginx在Mac上搭建自己的服务器。 我相信很多朋友肯定是第一次听到Nginx,关于它具有怎样的传奇,这儿肯定说不完也说不透. 有兴趣的朋友可以自行google或者baidu. WHY 为什么要搭建自己的服务器呢。 好处肯定多多,这儿说一条——模拟数据。 很多时候,我们在前端开发的过程中,API接口没有做好. 当我们要铺界面时,如果等待API的开发完成,无疑是件很耽误工作的事情。 还有一点,即使API完成了,我们开发完项目时,需要自测各种极限的数据。例如 约定好返回的是NSString,如果返回的是NSNumber,你会崩吗? 约定好的一个字段有返回值,突然间返回为null,你会崩吗? 约定好的label上的赋值文本是最多7个字,突然给你77个字,你会变得很丑吗? 有人问了,不是约定好了吗? 话说API也是人开发的,你写的客户端还会crash呢,就不允许人家后台出错啦??? 讲道理嘛大兄弟! HOW 复杂来说,这是件很难的事情,因为无论是Nginx,还是它所需要的准备工作,都是一个个庞然大物。搞不懂! 你需要安装Nginx,你可以自己独立装,也可以用别的包安装. 后者那推荐的是Homebrew.这也是下面我带大家一起来做的。 如果是前者,不要问我,我装了一下午,然后失败了。 简单来说,跟着我来做,几个步骤,几分钟,带你实现。 [html] view plain copy 平台:Mac 系统:10.11.1   1. 安装Homebrew 2. 安装Nginx 3. 启动Nginx 4. 配置JSON文件 5. 配置Nginx 6. 展现成果 1.安装Homebrew 打开终端,输入: [html] view plain copy ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”   跟着步骤走。终端都有提示。 2.依赖Homebrew安装Nginx 依旧在终端中 [html] view plain copy brew install nginx   这个等待时间会比较长。如果你仔细看了终端的进程。你会发现你用homebrew安装是多么聪明了。其实在安装nginx之前还要帮你安装很多别的,如果你独立安装,是很费劲的。。。 3.启动Nginx 依旧在终端里,输入 […]

centos7 php7.0 升级到php7.1

备份之前的php7.0(这很重要,非常重要) 如果这一步没有做的话,直接升级,我敢确定90% 你服务器就挂了,至于为什么呢,因为你之前的配置都没有了呗,而新安装的php7.1 配置是新的,没有了各种扩展,你服务器怎么跑起来。当然如果你什么扩展都没有安装,恭喜你,你可以不用备份 cp -P /usr/local/php /usr/local/php70 查看php7.0的configure 既然是升级,当然configure只能比以前多而不能少了,如果你忘记了以前的configure(肯定没人记得),查看phpinfo php -i | grep configure 替换一下就可以获得之前的configure 命令 php -i | grep configure | sed -e “s/Configure Command => //; s/’//g” 下载php7.1源码 cd /usr/local/src wget -c http://cn2.php.net/get/php-7.1.0.tar.gz/from/this/mirror -O php-7.1.0.tar.gz tar -zxvf php-7.1.0.tar.gz cd php-7.1.0/ 开始安装7.1 cd php-7.1.0 ./configure –prefix=/usr/local/php –exec-prefix=/usr/local/php –bindir=/usr/local/php/bin –sbindir=/usr/local/php/sbin –includedir=/usr/local/php/include –libdir=/usr/local/php/lib/php –mandir=/usr/local/php/php/man –with-config-file-path=/usr/local/php/etc –with-mhash –with-openssl –with-mcrypt –enable-mysqlnd –with-mysqli=mysqlnd –with-pdo-mysql=mysqlnd –with-gd –with-iconv […]

Websocket原理

一、websocket与http WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算) 首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解 有交集,但是并不是全部。 另外Html5是指的一系列新的API,或者说新规范,新技术。Http协议本身只有1.0和1.1,而且跟Html本身没有直接关系。。通俗来说,你可以用HTTP协议传输非Html数据,就是这样=。= 再简单来说,层级不一样。 二、Websocket是什么样的协议,具体有什么优点 首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的PHP生命周期来解释。 HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。 在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。 教练,你BB了这么多,跟Websocket有什么关系呢?_(:з」∠)_好吧,我正准备说Websocket呢。。 首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。 首先我们来看个典型的 Websocket 握手(借用Wikipedia的。。) GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com 熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。我会顺便讲解下作用。 Upgrade: websocket Connection: Upgrade 这个就是Websocket的核心了,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。 Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理。 然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~ 最后, Sec-WebSocket-Version 是告诉服务器所使用的 Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 脱水: 服务员,我要的是13岁的噢→_→ 然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦! […]

emoji表情 Unicode代码大全

emoji表情有很多种版本,其中包括Unified、DoCoMo、KDDI、Softbank和Google,并且不同版本用于表示同一符号表情的Unicode代码也不相同。本篇文章,给出SoftBank(日本软银集团)版本的emoji表情代码表(网上一般称之为SB Unicode,指的就是它):