V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Damnever
V2EX  ›  Python

吐槽 Python

  •  
  •   Damnever ·
    damnever · 2015-11-19 16:01:53 +08:00 · 3253 次点击
    这是一个创建于 3102 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我猜你们看到 吐槽 两个字就会进来的。。。

    撸了个高仿 Ubuntu 不带参数的 ping 程序。这里: https://github.com/Damnever/dping

    撸的过程中考虑到一个问题,就是计算丢失率的时候,如果发送了一个报文,发送的报文计数(就叫 transmitted )加一,接受到一个报文,接受到的报文计数(就叫 received )加一。如果发送了一个报文并且 transmitted 加一, 如果此时按下Ctrl + C,假设发完这个之后是一定能收到响应报文的,那么 received 就会比理论值少一,丢失率就变大。

    当时就想 Python 是否能阻塞 SIGINT ,结果大失所望。。。最后我这种 C 语言学渣还得强行撸点 C 代码,反正是能用。。。 除了运行效率这种人人皆知在脚本语言中不算大槽点的问题, Python 终于让我失望了。。。

    第 1 条附言  ·  2015-11-19 16:40:14 +08:00
    把最后一个报文丢掉是最直接的,但是那些说忽略掉 SIGINT ,我表示很无辜。。。
    第 2 条附言  ·  2015-11-19 16:48:21 +08:00
    我的需求的确有点奇葩,见谅。。。
    jiang42
        1
    jiang42  
       2015-11-19 16:14:19 +08:00 via iPhone
    为什么不把你尝试的方法发出来呢?为什么不谷歌一下呢?其实你让我挺失望的。
    clino
        2
    clino  
       2015-11-19 16:16:57 +08:00
    看不懂楼主上面关于丢失率的那些描述...
    Damnever
        3
    Damnever  
    OP
       2015-11-19 16:17:01 +08:00
    @jiang42

    。。。不知道你仔细看没

    Google 了,要不然我怎么会说我失望。源码就是上面那个链接,把 C 代码发一遍吧 https://github.com/Damnever/dping/blob/master/dping/_sigpending.c
    Damnever
        4
    Damnever  
    OP
       2015-11-19 16:20:25 +08:00
    @clino

    如果发了一个包, transmitted 就加一,你`Ctrl + C`中断程序,你就收不到响应了, 假设这个响应是一定能收到的,不会丢失,但是程序已经挂了,那么 received 就比理论上少一,那么丢失率 (transmitted - received) / transmitted 就比理论上大一点。
    9hills
        5
    9hills  
       2015-11-19 16:20:45 +08:00
    最简单的办法难道不是直接丢弃最后一个报文的计数么。。

    你的场景不就是 run 一个 ping ,然后中途 ctrl+c 导致计数有 1 的误差
    felixzhu
        6
    felixzhu  
       2015-11-19 16:20:49 +08:00
    楼主做这个的目的是什么?系统的 PING 实现也是无视掉了最后一个包啊。

    ➜ ping www.baidu.com
    PING www.a.shifen.com (61.135.169.125): 56 data bytes
    ^C
    --- www.a.shifen.com ping statistics ---
    1 packets transmitted, 0 packets received, 100.0% packet loss
    9hills
        7
    9hills  
       2015-11-19 16:21:27 +08:00
    @Damnever 如果不管最后一个报文收到还是没收到都直接丢弃相关的计数呢。
    lhbc
        8
    lhbc  
       2015-11-19 16:23:36 +08:00
    把发送数用两个计数器不就行了
    send 发出数
    transmitted timeout 或 received 后 +1

    然后直接计算 received / transmitted
    zjq426
        9
    zjq426  
       2015-11-19 16:27:07 +08:00
    python 按下 control+c 不是会抛出一个 KeyboardInterrupt 异常么,如果只是想正常中止可以捕获这个并处理。如果是要处理 signal 貌似也可以通过 signal.signal 库来注册你的 handler.

    http://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python
    Damnever
        10
    Damnever  
    OP
       2015-11-19 16:28:14 +08:00
    @9hills
    @felixzhu

    好吧,实际上是我又不想把它丢掉,既然发出去了。。。
    Damnever
        11
    Damnever  
    OP
       2015-11-19 16:29:44 +08:00
    @zjq426 这个我知道,我是要阻塞 SIGINT
    zjq426
        12
    zjq426  
       2015-11-19 16:34:18 +08:00
    @Damnever 貌似 python 只能捕获 signal 并忽略,并不能阻塞 signal 。我好像明白你的槽点了。
    jiang42
        13
    jiang42  
       2015-11-19 16:36:59 +08:00 via iPhone
    @Damnever 再去看看提问的艺术

    我看了 readme ,如果是你 readme 里那种情况的话
    https://gist.github.com/anonymous/c92e30504540a28c2788
    Damnever
        14
    Damnever  
    OP
       2015-11-19 16:38:28 +08:00
    @jiang42 你是忽略掉了 SIGINT 啊,大哥!!!
    jiang42
        15
    jiang42  
       2015-11-19 16:42:26 +08:00 via iPhone
    @Damnever 可是这个行为和你 readme 里面的示例是一样的。所以你期望的行为是怎么样的?
    mengzhuo
        16
    mengzhuo  
       2015-11-19 16:42:33 +08:00 via iPhone
    跟语言没干系啊,这都啥奇葩需求
    你都终止进程了 还想让死人干什么?
    est
        17
    est  
       2015-11-19 16:42:44 +08:00
    Damnever
        18
    Damnever  
    OP
       2015-11-19 16:46:00 +08:00
    @mengzhuo 额。。。
    Damnever
        19
    Damnever  
    OP
       2015-11-19 16:46:39 +08:00
    @est 。。。估计是我的文笔太差了
    linescape
        20
    linescape  
       2015-11-19 16:48:26 +08:00
    @felixzhu 我想知道 手为啥有这么快。。。
    Damnever
        21
    Damnever  
    OP
       2015-11-19 16:49:30 +08:00
    @jiang42 你还是没有 get 到
    jiang42
        22
    jiang42  
       2015-11-19 16:51:10 +08:00 via iPhone
    @Damnever 我确实没有 get 到,你提供一个你的程序可以而我的程序不行的 testcase 呗
    Damnever
        23
    Damnever  
    OP
       2015-11-19 16:52:48 +08:00
    @jiang42 这个跟信号安全可以扯上那么一丁点关系,你自己了解下吧
    scenix
        24
    scenix  
       2015-11-19 17:01:04 +08:00
    https://docs.python.org/3/library/signal.html 楼主我在这里看到有个 signal.sigpending()的函数,不知道你用不用的上。
    clino
        25
    clino  
       2015-11-19 17:01:58 +08:00
    楼上 @9hills 说的是对的"最简单的办法难道不是直接丢弃最后一个报文的计数么。。 " 合理
    因为你的程序已经终止,这最后一个报文你是没办法知道到底对不对的,所以不能计算最后这一个
    Damnever
        26
    Damnever  
    OP
       2015-11-19 17:03:55 +08:00
    @scenix 好吧, Python 3 不是很了解,看来是时候抛弃 Python 2 了
    scenix
        27
    scenix  
       2015-11-19 17:06:20 +08:00
    @Damnever 我虽然也是 python2 用的多 不过看到大部分的库都支持 3 了 感觉 3 是未来啊
    jiang42
        28
    jiang42  
       2015-11-19 17:09:26 +08:00 via iPhone
    @Damnever 有点懂了,不过在我看来实现你的需求不需要 block 。 Python 2 的文档里明确说明不支持 block 。 Python 3 提供 signal.pthread_sigmask 。我不知道你用的 Python 版本,不过是时候抛弃 2 了
    Damnever
        29
    Damnever  
    OP
       2015-11-19 17:13:04 +08:00
    @jiang42 的确不需要,但是我想到了, Python 2 却不支持,还要自己动手,所以这是槽点
    jiang42
        30
    jiang42  
       2015-11-19 17:17:06 +08:00 via iPhone
    @Damnever 其实,就是这样的。。。不然要 C API 干嘛。。。你可以提交 patch 啊,反正是开源的。。。我看了下,似乎 ruby 也不能 block 。。。
    CRVV
        31
    CRVV  
       2015-11-19 23:33:28 +08:00
    确实看到吐槽就进来了,于是进来吐槽
    1 、 A simple ping program written in Python
    2 、费了这么大的劲,如果有个包在第 4 秒回来了,你这程序还是没把丢包率算对
    3 、实现这个需求显然有简单得多的方法,上面也有人说了。你就非要搞这个 SIGINT ,于是成功地把简单的问题复杂化了
    4 、有 Python3 不用,还 from __future __ import xxx , 明摆着自己给自己找麻烦
    Damnever
        32
    Damnever  
    OP
       2015-11-19 23:49:20 +08:00
    @CRVV

    感谢吐槽,首先,第一二点我同意;然后第三点我实际上也在吐槽我自己,学习阶段给自己挖点坑没什么不好,但不能知难而退;第四点,我是为了把 2 和 3 都给兼容了,你认为这种小程序还这样就是找麻烦,我也没辙。。。
    CRVV
        33
    CRVV  
       2015-11-20 08:50:36 +08:00
    @Damnever
    似乎有个误解,所以回一下
    我写的 4 其实是对应 24 和 28 楼
    但是我没写清楚...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2620 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 15:41 · PVG 23:41 · LAX 08:41 · JFK 11:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.