Odd*_*ing 21 python real-time urllib2
我用urllib2的是build_opener()创造一个OpenerDirector.我正在使用它OpenerDirector来获取慢速页面,因此它有一个很大的超时.
到现在为止还挺好.
但是,在另一个线程中,我被告知要中止下载 - 假设用户已经选择退出GUI中的程序.
有没有办法发出urllib2下载应该退出的信号?
没有干净的答案.有几个丑陋的.
最初,我在这个问题中提出了被拒绝的想法.由于很明显没有正确的答案,我决定将各种次优选择作为列表答案发布.其中一些受到评论的启发,谢谢.
如果OpenerDirector提供取消操作员,理想的解决方案.
它不是.图书馆作者注意到:如果你提供长时间的慢操作,你需要提供一种方法来取消它们,如果人们要在真实世界的应用程序中使用它们.
作为其他人的一般解决方案,这可能有效.通过较小的超时,它可以更好地响应环境的变化.但是,如果它们在超时时间内没有完全完成,它也会导致下载失败,所以这是一个权衡.在我看来,这是站不住脚的.
同样,作为一般解决方案,这可能有效.如果下载包含非常大的文件,您可以用小块读取它们,并在读取块后中止.
不幸的是,如果(在我的情况下)延迟是在接收第一个字节而不是文件的大小,这将无济于事.
虽然有一些侵略性技术可以杀死线程,但根据操作系统的不同,不建议这样做.特别是,它们可能导致死锁.请参阅Eli Bendersky的两篇 文章(来自@JBernardo).
如果用户已触发中止操作,则最简单的方法是不响应,并且在打开操作完成之前不对请求执行操作.
您的用户是否接受这种无响应(提示:否!),取决于您的项目.
它还继续对服务器提出要求,即使已知结果是不需要的.
如果创建一个单独的线程来运行操作,然后以可中断的方式与该线程通信,则可以丢弃被阻塞的线程,然后开始处理下一个操作.最终,线程将解除阻塞,然后它可以正常关闭.
该线程应该是一个守护进程,因此它不会阻止应用程序的完全关闭.
这将为用户提供响应,但这意味着需要继续支持它的服务器,即使不需要结果.
正如@ Luke的回答所述,有可能为标准Python库提供(脆弱的,不可移植的?)扩展.
他的解决方案将套接字操作从阻塞更改为轮询.另一个可能允许通过该socket.shutdown()方法关闭(如果这确实会中断被阻塞的套接字 - 未经测试.)
基于Twisted的解决方案可能更清晰.见下文.
所述扭曲框架提供了一个替换设置该是事件驱动的网络操作库.我理解这意味着所有不同的通信都可以由没有阻塞的单线程处理.
有可能导航OpenerDirector,找到阻塞的基本套接字,并直接破坏它(socket.shutdown()足够吗?)使其返回.
呸.
读取套接字的线程可以移动到单独的进程中,并且可以使用进程间通信来传输结果.这个IPC可以由客户端提前中止,然后整个过程就可以被终止.
如果您可以控制正在读取的Web服务器,则可能会发送一条单独的消息,要求它关闭套接字.这应该导致被阻止的客户端做出反应.
| 归档时间: |
|
| 查看次数: |
2436 次 |
| 最近记录: |