进程间通信

进程间通信(InterProcess Communication, IPC),进程通信就是指不同进程间进行数据共享和数据交换。

Windows进程间通信

文件映射

  文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。
  Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。
  应用程序有三种方法来使多个进程共享一个文件映射对象。
  (1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。
  (2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。
  (3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、邮件槽等)把对象句柄传递给第二个进程。第二个进程复制该句柄就取得对该文件映射对象的访问权限。
  文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。

文件映射作用

  • 系统使用内存映射文件,以便加载和执行exe和DLL文件。这可以大大节省页文件空间和应用程序启动运行所需的时间。
  • 可以使用内存映射文件来访问磁盘上的数据文件。这使你可以不必对文件执行I/O操作,并且可以不必对文件内容进行缓存
  • 可以使用内存映射文件,使同一台计算机上运行的多个进程能够相互之间共享数据。
  • Windows确实提供了其他一些方法,以便在进程之间进行数据通信,但是这些方法都是使用内存映射文件来实现的,这使得内存映射文件成为单个计算机上的多个进程互相进行通信的最有效的方法

实现详细过程

Flask之蓝图(Blueprint)

随着功能的添加,路由越来越多,view层的拆分变成了刚需

方式

  1. 模块Module
  2. 蓝图Blueprint

实现

Module

开始是通过Module来实现,但是运行时收到Flask的提示Module已经被摒弃,建议通过Blueprint来实现,就不在多说,留个Git上别人的实例Module

Blueprint

  • 创建蓝图和路由(errors.py)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from flask import Blueprint
    # 创建蓝图
    err = Blueprint('err', __name__)
    # 404
    @err.app_errorhandler(404)
    def page_not_found(e):
    return render_template('404.html'), 404
    # test
    @err.route('/nimei', methods=['POST', 'GET'])
    def nimei():
    return 'nimei'

Python友好显示时间戳

友好时间戳

之前考虑通过Mement.js来处理,最后没去折腾,直接用jinja2的过滤器简单处理,现在直接通过后台自己实现,可根据需要自定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# -*- coding: utf-8 -*-
import datetime
# 计算星期几
def get_weekday(date):
week_day_dict = {
0 : '星期一',
1 : '星期二',
2 : '星期三',
3 : '星期四',
4 : '星期五',
5 : '星期六',
6 : '星期日',
}
day = date.weekday()
return week_day_dict[day]
# 时间格式化
def datetime_format(value, format="%Y-%m-%d %H:%M"):
print value, type(value)
return value.strftime(format)
# 时间差
def datetime_delta(time):
now = datetime.datetime.now()
time_date = now.date() - time.date()
days = time_date.days
seconds = (now - time).seconds
# 星期一 8:00
if days <= 6:
if days < 1:
if seconds < 60:
return '几秒前'
elif seconds < 3600:
return '%s分钟前' % int(seconds / 60)
else:
return datetime_format(time, '%H:%M')
if days < 2:
return '昨天 ' + datetime_format(time, '%H:%M')
return get_weekday(time) + ' ' + datetime_format(time, '%H:%M')
else:
return datetime_format(time, "%Y-%m-%d")
print datetime_delta(datetime.datetime.strptime('2015-03-29 14:13:00', "%Y-%m-%d %H:%M:%S"))

广场KVDB设计

广场功能

  • 发状态
  • 评论状态(回复评论)
  • 状态、评论赞同或反对
  • 消息提醒

KVDB设计

状态信息记录
uid根据时间戳生成的唯一的倒序值,uid = 未来某个时间戳-当前时间戳(就取3000年吧,如果高小恋到时候还没死的话),KVDB的get请求自动从大到小排序。
状态基本信息

用户状态记录
记录用户所发状态,uid根据时间倒序,用于加载用户自己发布的状态。
用户状态记录

评论、回复记录
评论、回复记录

状态赞同、反对记录
状态赞同、反对

评论(回复)赞同、反对记录
评论(回复)赞同、反对

状态关注者记录
状态有新的回复时通知所有follower
状态关注者

消息提醒记录
有新的回复或评论时添加消息提醒记录。
消息提醒记录

一代的困惑

本文源于公众号麦子熟了的“我们这一代的困惑”(强烈推荐),感觉确实说了很多我们这一代人应该反省的一些事情,感触颇多,于是记录下来,就当引导自己。


做喜欢的事

清楚其中的随机性并能心平气和的接受的事才是你想做的

一般事情可分由下面几种情况决定:

  • 随机性决定:赌博,彩票……
  • 能力决定:四六级……
  • 随机性和能力共同决定:创业,恋爱,梦想 and so on

  绝大多数人在做由第二条所决定的事情,少部分人在做另外两种。


付出与回报

能力没有达到一定层度的时候,连面对随机性的资格都没有

  很多时候别人说我们比较功利的时候我们还会义正言辞的反驳,但是当你认真读了这篇文章,或许你就没了义正言辞的底气。

  大多数时候我们太过于追求及时的反馈,做一些事情的时候总希望做一步就能很快看到对应的效果,希望自己的付出能得到及时的“回报”,因为这样才能激励你自己继续下去。但是很多时候很多事情是一时半会儿是看不到效果的,甚至很长一段时间都没有任何收获。

  这也让我更容易理解为什么初恋的感觉总被大家怀念?小时候为什么更容易学习琴棋书画?初高中时为什么可以毫无察觉的在书店坐上一整天?

SAE中MySQL备份与恢复

手动备份:

由于SAE的备份和恢复执行都有一定的缓冲时间,对于突发情况不能等待,就需要手动去执行,DeferredJob的管理界面可以直接备份整个数据库的数据,并且提供下载。恢复的时候可以直接使用phpMyAdmin来恢复(数据量小于8,192 KB)

(1)解压DeferredJob上下载下来的数据包
(2)添加扩展名sql
(3)删除所有表的LOCK和UNLOCK语句(SAE用来避免数据库数据写入冲突语句,也就意味着我们在导入的时候不能对数据库进行写操作)
(4)phpMyAdmin导入sql文件
当然也可以直接使用phpMyAdmin导出数据然后在导入。


自动备份

自动备份需要用到DeferredJob(数据备份)、Cron(定时任务)和Mail(邮件发送)

Python中instancemethod、staticmethod和classmethod

方法说明

instancemethod:实例方法,函数定义前不加任何修饰符
classmethod:类方法,@classmethod 修饰符
staticmethod:静态方法,@staticmethod 修饰符
举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test(object):
class_var = "class var" #类成员
def __init__(self, object_var = "object var"):
self.object_var = object_var #实例成员
def Fun(self)://定义了实例方法
print("object")
@classmethod
def classFun(cls)://定义了类方法
print("class")
@staticmethod
def staticFun()://定义了静态方法
print("static")

相同点

均可以继承,均可以通过类和实例调用,即:

1
2
3
4
5
6
7
t = Test()
Test.Fun()
t.Fun()
Test.classFun()
t.classFun()
Test.staticFun()
t.staticFun()

不同点

  • instancemethod至少需一个self参数,可以通过self访问实例成员。

  • classmethod需要cls类变量作为参数传递,无法访问实例成员,可访问类成员,并且有子类继承时,调用该方法传入的是子类,而非父类。

  • staticmethod可以不需要参数,无法访问实例成员和类成员,相当于一个全局函数