Algorithm
LeetCode/205_同构字符串
Review
克服上瘾的3条准则
一、你需要一个爱好,这能带来美好的情绪
二、照顾好自己的身体,养成健康的饮食习惯,并且定期锻炼
三、主动社交,联系老朋友,结识新朋友,你会感受到与他人连结的快乐感
Tips
Python防止listdir阻塞
CPython的实现os.listdir使用特定于平台的C库调用来读取目录的内容。在类似Unix的平台上,它们是opendir(3)and readdir(3),而在Windows上则使用FindFirstFileand FindNextFile。
在无法访问的网络文件系统的情况下,这些调用的行为将取决于操作系统。当使用Linux或Windows时,它们肯定会在系统命令(例如lshang)挂起的情况下挂起。为了防止任意长时间的停顿,可以使用专用框架,例如asyncio和twisted,它们使用非阻塞IO。但是,使用这些框架可能会让人望而生畏,并且通常需要在整个应用程序和整个程序中使用它们来构建事件驱动的模型。
确保存在网络文件系统时IO系统调用不会阻塞的一种更简单且对初学者友好的方法是使用线程。例如,这是一个safe_listdir返回目录内容的函数,或者None调用所花费的时间超过指定的超时时间:
1 2 3 4 5 6 7 8 9 10 11
| import os, threading
def safe_listdir(directory, timeout): contents = [] t = threading.Thread(target=lambda: contents.extend(os.listdir(directory))) t.daemon = True t.start() t.join(timeout) if t.is_alive(): return None return contents
|
在Python 3中,可以使用出色的concurrent.futures软件包。它不仅简化了实现,而且还自动限制了多次safe_listdir调用时创建的线程的数量,并确保将引发的异常os.listdir正确传播到调用者:
1 2 3 4 5 6 7 8 9
| import os, concurrent.futures pool = concurrent.futures.ThreadPoolExecutor()
def safe_listdir(directory, timeout): future = pool.submit(os.listdir, directory) try: return future.result(timeout) except concurrent.futures.TimeoutError: return None
|
参考
os.listdir可以挂在网络驱动器上吗?它使用什么系统调用?
Share
Pyhton防止listdir阻塞进阶
使用超时装饰器
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import sys import threading from time import sleep, time
class KThread(threading.Thread): """Subclass of threading.Thread, with a kill() method.""" def __init__(self, *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.killed = False def start(self): """Start the thread.""" self.__run_backup = self.run """Force the Thread to install our trace.""" self.run = self.__run threading.Thread.start(self) def __run(self): """Hacked run function, which installs the trace.""" sys.settrace(self.globaltrace) self.__run_backup() self.run = self.__run_backup def globaltrace(self, frame, why, arg): if why == 'call': return self.localtrace else: return None def localtrace(self, frame, why, arg): if self.killed: if why == 'line': raise SystemExit() return self.localtrace def kill(self): self.killed = True
def list_file_timeout(seconds): def timeout_decorator(func): def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs): result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs)) def _(*args, **kwargs): result = [] '''create new args for _new_funcbecause we want to get the func return val to result list ''' new_kwargs = { 'oldfunc': func, 'result': result, 'oldfunc_args': args, 'oldfunc_kwargs': kwargs } thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) thd.start() thd.join(seconds) alive = thd.isAlive() '''kill the child thread''' thd.kill() if alive: alert_exce = u'list_file timeout for [%d s].' % seconds print alert_exce else: return result[0] _.__name__ = func.__name__ _.__doc__ = func.__doc__ return _ return timeout_decorator
class Foo: TEST = 5
@list_file_timeout(TEST) def list_file(self): sleep(10)
foo = Foo() foo.list_file()
|
单线程生成文件,并上传到S3桶中
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
| vim gen.sh
fmt=output.%05d cd lm
for i in $(seq 1 3) do head -c 512K /dev/urandom > `printf $fmt $i` done
s3cmd --configure \ --access_key=<access_key> \ --secret_key=<secret_key> \ --region=<region> \ --host=<endpoint> \ --host-bucket=<endpoint> \ --no-ssl
s3cmd put lm s3://lm-noscan-bk --recursive
|
优化: vdbench 多线程生成文件