Python 从多人聊天室开始谈系列 - 线程同步与读者写者模型
接下来,我们不可避免的会遇到线程同步问题,这是因为我们涉及到了共享数据的问题(也就是一个数组)。
我们来看看Python的锁:
threadLock = threading.Lock()
在同步的地方,用:
接下来,我们不可避免的会遇到线程同步问题,这是因为我们涉及到了共享数据的问题(也就是一个数组)。
我们来看看Python的锁:
threadLock = threading.Lock()
在同步的地方,用:
接下来我们差不多能聊起来了,剩下的就是解决上一篇中我们遗留的登出移除问题以及做一个界面,那样我们就能给更多的人用啦。
选择Tkinter,主要是,作为一个没有其他语言GUI基础的人,入门最简单粗暴的方法可能就是这个了。
关于Tkinter,网上的资源其实说不上太多,还是比较难找的,尤其是对于一个写惯了HTML/CSS的,其实是挺痛苦的。
Tkinter的布局教程可以看这里:http://effbot.org/tkinterbook/grid.htm
完成了上一个版本,我们会发现,根本聊不起来啊!
问题的关键在于,我们现在的程序,一次只能干一个事情,你让我等待输入了,我就不能好好输出了。
所以我们需要在此引入多线程的概念,多线程的概念,简单的来说,就是,我因为只有一个人,你让我去干一件事还可以,两件事我不行,那多加一个人,总可以干了。
那么阻塞呢,意思就是说:由于我干了这个,不能干那个,我们把这个现象叫做阻塞。
概念都理解了之后,我们知道了,只要多加一个线程就行了!
实现多线程有几种方法,具体来说,我们可以看一下这篇:
http://www.cnblogs.com/tqsummer/archive/2011/01/25/1944771.html
接下来我们首先略过了Python的基础,这一部分,随便找一本Python的书看看就行了,习惯了没有;
的人生之后,在必须的语句里记得加:
,基本上你就进入了Python模式。
当然,由于赶时间,这里很多可能不是最优写法,大家可以去GitHub提出=v=。
官网Demo有云:
# Echo server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
这次的操作系统课设要做聊天室,众所周知的是,Node.js家有强大的socket.io,官网的demo就能让你分分钟速写聊天室——但是并没有什么卵用。
从操作系统的角度,我们决定从底层出发,去挖掘一下究竟一个轮子是怎么样实现的。
首先先决条件,我们需要学习:
目标是最快的速度学习并实现我们的一个简单而且比较稳定的聊天室。
我们首先先来简单的了解一下Socket的模式:一个Client与一个Server建立连接,那么多个Client的情况,就需要把Server作为转发器来进行消息的转发,然后由Server推送到另一个Client中。
在GitHub中有完整的代码,接下来的介绍也是按照我的版本迭代顺序来的=v=:https://github.com/csvwolf/sky-chatting-room
在上一篇文章中,我们试图获取Bing的壁纸,但是却发现它虽然是个标准的json,但不支持跨域,响应头没有:Access-Control-Allow-Origin: *
。
上一次用curl还是刚学PHP的时候复制粘贴的,现在感受深多了,看得懂到底是怎么回事了,不过我们的需求也比上次简单多了,上次是缓存图片到本地,而这次我们只要把内容输出就可以了。
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1");
curl_setopt($ch, CURLOPT_HEADER, 0);
$out = curl_exec($ch);
curl_close($ch);
说来惭愧,写了这么久的前端(大概),还没有使用过jsonp(后来我发现假期用Angular+Rails使用过。。。http://codesky.me/archives/rails-solve-cross-query.wind),这次在微博中,一个好友遇到了一个需要跨域的问题,那么机会来了。
我第一反应就是jsonp,尽管他说不可以,然而我还是想要试试看。
用最顺手的jQuery吧,话虽如此,jQuery也快忘了。
学校里有作业,需要实现生产者消费者模型,最简单的就是用synchronized同步锁一包,什么事情都没有了,不过由于是从最外层包起来的,所以总体而言就Low很多了。
一共用了四种方法,心好累:
Ruby学了主要作用大概也就是写写脚本了(毕竟传说中的Python/Ruby二选一),躺在床上想到因为复制黏贴下来少回车,在有的Markdown中会解析为没换行,有的则是<br/>
,这让人非常的烦躁!所以需要处理一下,怎么处理最快——用脚本。
首先先匹配,在Ruby正则表达式中,+
匹配一次或以上,我们需要匹配\n
,所以需要用多行的模式m
。
re = Regexp.new(/\n+/m)
匹配替换用的是String.gsub
方法。表示替换全部,sub
只替换首次匹配的部分。
result = file.gsub(re, "\n\n")
上次在仿制Hokster-domain-index时,想做一些tooltips的效果,但自己实际做起来却不知道从何下手,于是决定单独制作Tooltips,于是之后的SkyTips应运而生。
其实也还好,花了两天时间,当然之前也做了一些准备工作,比如前一篇文章中的那些东西,其实是Tooltips制作学习的衍生产物吧。
SkyTips讲究简单实用,我Javascript水平还很臭,所以,能用CSS的我绝不会用JS去做(这也是为了避免自己太过依赖JS并练习CSS),可以用纯粹的引入CSS来使用,具体在发布页都有说,下载可见:https://github.com/csvwolf/SkyTips
如果有什么Bug,请留言wwww如果能给我一些指导性建议就更好啦。
当然在测试完三大浏览器之后,发现其实SkyTips!不足之处太多了,还有很多值得改进的余地,甚至说是重写,这也是后话了=w=