复制这段内容后打开百度网盘手机APP,操作更方便哦 链接: https://pan.baidu.com/s/1UgZ0DESwZVhrHokVAUlWyw 提取码:hcr3
[心情]人生的十字路口
上一个还是2012年,那时还能打Dota排遣,只是坚持不下去;
如今感觉是缺乏方向与信仰,想放弃却无路可退;
想做点有意义的工作,也能多挣点钱才好,选择?。。。
[2019][积分落户]积分落户公示名单汇总
2019积分落户公示名单.xlsx
链接:https://pan.baidu.com/s/1IjZqoP3aFq_uxT7v1xS4_w 提取码:ltyq 复制这段内容后打开百度网盘手机App,操作更方便哦
PS:
申请人年度总积分:77.83
申请人年度总排名:50268
*********************
落户难度真大,难以想象。。。
[吐槽]打开浏览器,却不知道看什么内容。。。
最近常常有这样的感觉,打开浏览器,不知道上哪个网站好,也不知道自己想干些什么,都提不起兴趣。。。
难道是压力太大了?
兴趣…
爱好…
休闲?
娱乐?
貌似这些通通都木有了,打开手机不是看新闻就是看小说,无聊的快要疯了…
想找个事情,能兼职多挣点钱,能持之以恒的为之付出,好难…
[TensorFlow]新的开始
[GitHub]推出了Sponsors功能……
[Python][Django][asyncio]关于多线程、协程以及异步在Django中的应用
在开发环境中,Django默认用runserver方式启动,请求默认是支持多线程的,可以通过加上
--nothreading |
参数,禁止多线程运行;
但是在生产环境中,都会用uWSGI作为前置启动方式,它是默认采用多进程方式工作,每个进程是单线程运行,可以通过加上–threads设置单个进程运行的线程数;
Important!!!
重要的事情说三遍,单进程单线程的工作模式会导致工程中使用threading启动新的线程并不会一直工作,只在网络有请求到来时,主线程运行的那段时间内,新线程才会同步运行!!!
重要的事情说三遍,单进程单线程的工作模式会导致工程中使用threading启动新的线程并不会一直工作,只在网络有请求到来时,主线程运行的那段时间内,新线程才会同步运行!!!
重要的事情说三遍,单进程单线程的工作模式会导致工程中使用threading启动新的线程并不会一直工作,只在网络有请求到来时,主线程运行的那段时间内,新线程才会同步运行!!!
Gunicorn也是一种高性能的Python WSGI HTTP Server,默认工作方式是sync,也是多进程,每个进程默认单线程的工作方式,可以在配置文件中加入threads参数设置线程的数量(假定在gthread模式下生效!也就是会用gthread替代sync模式);
因为Python的全局解释器锁(GIL)的缘故,采用多线程进行上下文切换效率很低,不如异步框架(https://blog.csdn.net/yiliumu/article/details/77983393)。
下面针对gevent模式来说明:
1、gevent是基于协程(coroutine -based)的Python网络库
2、Event Loop是其核心概念
3、代码执行的同步、异步机制研究(http://sdiehl.github.io/gevent-tutorial/)
4、使用siege进行压力测试,sync在每个请求执行时间很短的情况下,是优于gevent模式,因为串行一次比切换一次loop消耗开销更小(0.01s);但是在单个业务超过3s以上的时候,串行阻塞时间会叠加、直到前一个业务返回,导致平均响应时间线性上升,如果client并发超过server的最大并发数量,所有请求将会严重等待。。。而基于协程的并行模式,只要不超过服务器的最大连接数,每个业务都只消耗该任务的网络I/O的等待时间,对于网络异步IO密集的任务很适用。。。例如:APNs推送。。。
5、Gunicorn下threading会正常工作,并不会停止运行!!!!
总结一下:多线程是线程调度,每个线程运行网络请求需要while循环等待网络数据,多个请求是竞争状态;协程是在Socket进入等待的时候,运行状态会挂起,进入下一个消息循环运行别的代码、直到收到信号数据准备好了,再切回来运行,尽量让工作都不闲着。。。因为是单线程,所以在本线程的cpu时间内运行的飞起。。。直到server的连接数满上限,不能接受多余的任务为止。。。
附上一张Gunicorn-Gevent初始化运行的调试堆栈和代码:
class GeventWorker(AsyncWorker): server_class = None wsgi_handler = None def patch(self): from gevent import monkey monkey.noisy = False # if the new version is used make sure to patch subprocess if gevent.version_info[0] == 0: monkey.patch_all() else: monkey.patch_all(subprocess=True) # monkey patch sendfile to make it none blocking patch_sendfile() # patch sockets sockets = [] for s in self.sockets: if sys.version_info[0] == 3: sockets.append(socket(s.FAMILY, _socket.SOCK_STREAM, fileno=s.sock.fileno())) else: sockets.append(socket(s.FAMILY, _socket.SOCK_STREAM, _sock=s)) self.sockets = sockets def notify(self): super(GeventWorker, self).notify() if self.ppid != os.getppid(): self.log.info("Parent changed, shutting down: %s", self) sys.exit(0) def timeout_ctx(self): return gevent.Timeout(self.cfg.keepalive, False) def run(self): servers = [] ssl_args = {} if self.cfg.is_ssl: ssl_args = dict(server_side=True, **self.cfg.ssl_options) for s in self.sockets: s.setblocking(1) pool = Pool(self.worker_connections) if self.server_class is not None: environ = base_environ(self.cfg) environ.update({ "wsgi.multithread": True, "SERVER_SOFTWARE": VERSION, }) server = self.server_class( s, application=self.wsgi, spawn=pool, log=self.log, handler_class=self.wsgi_handler, environ=environ, **ssl_args) else: hfun = partial(self.handle, s) server = StreamServer(s, handle=hfun, spawn=pool, **ssl_args) server.start() servers.append(server) while self.alive: self.notify() gevent.sleep(1.0) try: # Stop accepting requests for server in servers: if hasattr(server, 'close'): # gevent 1.0 server.close() if hasattr(server, 'kill'): # gevent < 1.0 server.kill() # Handle current requests until graceful_timeout ts = time.time() while time.time() - ts <= self.cfg.graceful_timeout: accepting = 0 for server in servers: if server.pool.free_count() != server.pool.size: accepting += 1 # if no server is accepting a connection, we can exit if not accepting: return self.notify() gevent.sleep(1.0) # Force kill all active the handlers self.log.warning("Worker graceful timeout (pid:%s)" % self.pid) [server.stop(timeout=1) for server in servers] except: pass def handle_request(self, *args): try: super(GeventWorker, self).handle_request(*args) except gevent.GreenletExit: pass except SystemExit: pass def handle_quit(self, sig, frame): # Move this out of the signal handler so we can use # blocking calls. See #1126 gevent.spawn(super(GeventWorker, self).handle_quit, sig, frame) if gevent.version_info[0] == 0: def init_process(self): # monkey patch here self.patch() # reinit the hub import gevent.core gevent.core.reinit() #gevent 0.13 and older doesn't reinitialize dns for us after forking #here's the workaround gevent.core.dns_shutdown(fail_requests=1) gevent.core.dns_init() super(GeventWorker, self).init_process() else: def init_process(self): # monkey patch here self.patch() # reinit the hub from gevent import hub hub.reinit() # then initialize the process super(GeventWorker, self).init_process() |
从运行过程可以看到,Gunicorn启动Django的时候,默认已经打上了全部的monkey补丁。。。同时也更改了wsgi.multithread=True。。。
[Android手机]IQOO、HUAWEI P30、OnePlus 7 Pro
截至2019年6月26日
IQOO 12G+128G 武士黑 3498元 https://shop.vivo.com.cn/product/10000467?colorSkuid=100938
HUAWEI P30 8G+64G 赤茶橘 3988元 https://www.vmall.com/product/10086705348665.html#10086949778766
OnePlus 7 Pro 6G+128G 曜岩灰 3999元 https://rush.oneplus.com/cn/oneplus-7pro?from=op7pro_header
倾向于选IQOO,内存够大,升级系统以后也毫无压力,散热优势,价钱便宜;
P30有点鸡肋,除了华为HongMeng OS有点可期待;
一加7Pro的屏幕非常不错,没其他亮点了。。。
网上反馈的很多问题大致了解了,IQOO音质一般,P30无特别缺陷,一加7Pro屏幕品控不够。
其实荣耀Magic2很不错,就是滑盖问题和肛裂问题会导致需要换屏幕,实在不想折腾。
想了一下手机应用的场景,多是用来听歌、看新闻,刷微信,支付宝,选便宜性价比高的就好了。。。唉,选择困难症。。。
[Android][Google Play]Support 64-bit architectures采坑(一)
项目jni代码比较旧,好几年没维护了……
1、项目采用ndk-build编译方式
2、项目使用Android.mk、Application.mk
3、修改Application.mk中的APP_ABI
APP_ABI := armeabi-v7a arm64-v8a |
error: invalid argument '-std=gnu99' not allowed with 'C++' |
5、修改Android.mk,移除’-std=gnu99’部分,继续编译,卡在了libyuv
6、关于libyuv与libjpeg的问题。。。这是一个超级大坑,因为最新的GitHub源代码采用了cmake的方式,于是单独编译了对应版本的so动态库,可是libyuv死活找不到部分jpeg的函数符号
zeonadmindeMac-mini-2:build zeonadmin$ make [ 49%] Built target yuv [ 51%] Built target yuvconvert [ 52%] Linking CXX shared library libyuv.so /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:78: error: undefined reference to 'jpeg_std_error' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:89: error: undefined reference to 'jpeg_CreateDecompress' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:0: error: undefined reference to 'jpeg_resync_to_restart' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:96: error: undefined reference to 'jpeg_destroy_decompress' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:121: error: undefined reference to 'jpeg_read_header' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:241: error: undefined reference to 'jpeg_abort_decompress' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:516: error: undefined reference to 'jpeg_start_decompress' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:542: error: undefined reference to 'jpeg_read_raw_data' /Users/zeonadmin/GitHub/libyuv/source/mjpeg_decoder.cc:526: error: undefined reference to 'jpeg_abort_decompress' clang++: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [libyuv.so] Error 1 make[1]: *** [CMakeFiles/yuv_shared.dir/all] Error 2 make: *** [all] Error 2 |
用ndk的nm查看符号,全部都在,卧槽不懂了。。。
只好单独将libyuv用单个android studio project的jni来build,结果就成功了
[armeabi-v7a] Gdbserver : [arm-linux-androideabi] libs/armeabi-v7a/gdbserver [armeabi-v7a] Gdbsetup : libs/armeabi-v7a/gdb.setup [armeabi-v7a] Install : libjpeg.so => libs/armeabi-v7a/libjpeg.so [armeabi-v7a] Install : libyuv.so => libs/armeabi-v7a/libyuv.so |
思考了一下原因,用的ndk都是来源AndroidStudio的ndk,TOOLCHAIN应该都是clang…
使用make VERBOSE=1 查看具体的链接库信息。。。
无解。。。
****2019年6月10日 周一****
休了一周的年假回来,整个人都通透了,终于发现了原因在build.sh上:
JPEG_SHARED_LIB=${JPEG_LIB_PATH}/libjpeg.so ... cmake -G"Unix Makefiles" \ -DANDROID_ABI=armeabi-v7a \ -DANDROID_PLATFORM=android-${ANDROID_VERSION} \ -DANDROID_TOOLCHAIN=${TOOLCHAIN} \ -DANDROID_ARM_MODE=arm \ -DCMAKE_ASM_FLAGS="--target=arm-linux-androideabi${ANDROID_VERSION}" \ -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \ -DCMAKE_C_FLAGS="${CFLAGS} -Wall -Werror -Wno-unused-parameter -fexceptions" \ -DJPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIR} \ -DJPEG_LIBRARY=${JPEG_SHARED_LIB} \ -DJPEG_SHARED_LIB=${JPEG_SHARED_LIB} \ ../ |
注意上面的JPEG_SHARED_LIB使用的是通配符变量,这样的写法cmake链接库的时候找不到,必须给动态库写绝对路径…
7、鉴于Android的样例推荐都采用了cmake编译,于是根据原来的Android.mk,重新翻译成CMakeLists.txt,还是很方便的,就是新东西里面的变量、函数不熟,导致试错成本太高,建议从AndroidStudio新建cmake编译的工程样例开始。
[北京市积分落户]2019年积分落户填报总结
5月22日开始申报,7月20日截止;
申报第一天已填报完成,并提交,小结一下过程。
1、与2018年不同的是,登录系统改用了北京市政府官方网站的统一登录路径:北京通,申报2019年积分落户需要注册北京通账号并完成L2、L3级别的实名认证
2、今年系统数据全部需要重填,官方所谓的4项不用填写项,去年也不用填……数据本来就在他们那,但是居住、教育居然还要重填一遍,真坑,重填不说,还要重新在线审核
3、今年系统采用全部在线审核的方式,去掉了现场审核,所以必须按照填报说明,上传证明材料
4、居住指标填写,去掉了2017年1月1日以前租房项,只有自有住房、2017年以后租房备案、2017年以后单位租房可选项;自有住房填写部分,规范了房产证的填写方式,只用填写x字x号部分;自有住房配偶部分,需要根据结婚证时间,填写配偶详情并审核通过后,才能填报配偶自有住房部分;如果有离婚复婚情况的,按离婚、再婚时间分段填写配偶栏位(即使是同一人,也分段填写);另外填报完成并保存,就进入在线审核系统后台审核,大概30分钟就有结果。
5、教育指标填写,今年特意分开了国内教育和其他部分,学历认证部分还是和去年一样,使用学信网的在线电子验证码;学位认证,由于去年是申请的纸质报告,填那个报告编号就好了;学历电子码在线审核很快,10分钟不到;学位审核花了上午3个小时。
6、职住转移,系统根据居住指标,自动计算是否符合居住转移,但是需要自己输入验证码,点击后面的计算按钮,得到结果了再保存
7、其他指标都无满足,但是仍需点击新增xxx,勾选“不满足xxx”,点保存(吐槽)
8、未完成的指标项,图标会是灰色状态,不能提交/预览
9、只有全部保存成功,提交才不会提示你有xxx未填写
10、提交成功,“预览/撤回”功能才可用,表示填报完成啦,静待出分即可。
备注:
关于房产证在线审核,官方提示过了,上住建委的官方网站去查一下自己的房本是否登记在系统中,不在的赶紧去窗口登记查询。
关于租房备案审核,有ZL和GL两种编码开头,ZL的去住建委的官方网站也能查到,否则也要去对应的地方登记查询。
关于学历、学位认证的,看本站前面几篇文章有介绍如何办理认证。