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
qile1
V2EX  ›  Python

threading 线程间通信如何控制线程运行及等待。

  •  
  •   qile1 · 2017-01-24 17:14:40 +08:00 · 2653 次点击
    这是一个创建于 2648 天前的主题,其中的信息可能已经有所发展或是发生改变。

    做一个伸手党。 我写了一个程序检测日志文件变化,如果日志文件新增,我启动一个线程按行读取数据后将内容解析放入数据库,记录行号到.ini 配置文件里面(大约需要 5-10 秒)。由于写入日志程序有时 5 秒内写入多次,导致上个线程还没有执行完,就又启动了一个线程。。。。。。,每个进程执行完写入记录行号时候偶尔会冲突,导致 ini 配置文件最后变为空白 0kb 大小。我想让第一个线程启动之后,再启动的线程等待第一个线程结束后再执行。 我代码部分内容如下:

         t2=threading.Thread(target=runReadLogFile,args=(1,))
        t2.start()#程序启动后先执行一次读取日志文件。
        当检测到日志文件修改后执行:
        t1=threading.Thread(target=runReadLogFile,args=(1,))
        t1.start()
    
    20 条回复    2017-01-29 01:47:44 +08:00
    kier
        1
    kier  
       2017-01-24 17:17:29 +08:00
    直接等线程结束再启动新线程,或者就保持一个线程,定时唤醒
    czheo
        2
    czheo  
       2017-01-24 17:55:00 +08:00
    you need a lock
    qile1
        3
    qile1  
    OP
       2017-01-24 19:38:58 +08:00
    @kier 你意思是不是 我在主线程里面定义 线程 1 ,日志文件被修改的时候我启动线程 1

    t2=threading.Thread(target=runReadLogFile,args=(1,))
    t2.start()#程序启动后先执行一次读取日志文件。
    t1=threading.Thread(target=runReadLogFile,args=(1,))#预先设置线程一,等待启动

    当检测到日志文件修改后执行:
    t1.start()#如果 t1 没执行完,再次调用会报错还是继续执行?
    ryd994
        4
    ryd994  
       2017-01-24 22:37:31 +08:00 via Android
    mahone3297
        5
    mahone3297  
       2017-01-24 22:49:14 +08:00
    弱弱问下大家:
    * lz 的这种收集日志到 db 的思路,是否 ok ?
    * 为什么不用 logstash ?
    kier
        6
    kier  
       2017-01-24 23:02:14 +08:00 via iPad
    @qile1 在 runReadLogFile 里去读 log ,处理完后 sleep 一段时间,再尝试去读
    qile1
        7
    qile1  
    OP
       2017-01-25 00:39:56 +08:00 via Android
    @kier 最开始是这样操作的。
    一个线程循环读文件
    但是到了后期文件大了,加入了日志文件修改检测后处理
    这样后期文件大了。不用平凡读取日志文件。
    latyas
        8
    latyas  
       2017-01-25 00:57:22 +08:00
    资源访问的临界区请用锁控制
    latyas
        9
    latyas  
       2017-01-25 00:57:40 +08:00
    或者单写多读,可以去掉锁
    sheep3
        10
    sheep3  
       2017-01-25 01:30:09 +08:00
    锁,信号量,都行。但个人感觉不是很合理。不说你这个方案本身(也许这是你当前场景的最佳选择),就说如果这个线程必须等上个线程完成后再开始任务,为什么不就开一个线程,循环从队列里面取。
    wjidea
        11
    wjidea  
       2017-01-25 01:54:03 +08:00
    multiprocessing.Manager()
    manager.Lock()
    kier
        12
    kier  
       2017-01-25 09:34:50 +08:00
    @qile1 文件大了又怎么样? open 后, seek 到对应位置直接读固定长度的内容,不会有性能问题的!
    另外,不管多少个线程,互斥操作同一个资源都是要顺序执行的,没法并行,所以根本提升不了速度
    qile1
        13
    qile1  
    OP
       2017-01-25 10:14:18 +08:00 via Android
    @kier 我读取日志文件是一次全部读取,计算行数。如果行数大于 ini 文件的记录值,就按行便利一遍,从记录行开始处理数据(这个操作时间长),日志单行长度不固定,如果从 seek 开始读取固定长度担心出现截取不全。想建立一个队列,里面只有一条,空就加入任务队列,满了就 try 一下捕获异常。
    但是不知道 treading 如何取队列并执行
    kier
        14
    kier  
       2017-01-25 10:28:19 +08:00
    @qile1 那为什么不直接记录当前读取位置呢?这样下次就可以直接 seek
    q397064399
        15
    q397064399  
       2017-01-25 16:58:43 +08:00
    加锁吧,没有其它办法
    q397064399
        16
    q397064399  
       2017-01-25 16:59:27 +08:00
    还有一个简单的办法 申请线程池 然后只有一个线程
    这样可以提交任务到阻塞队列
    xntop
        17
    xntop  
       2017-01-25 21:40:05 +08:00
    用信号量呗
    qile1
        18
    qile1  
    OP
       2017-01-27 01:30:35 +08:00 via Android
    发现还是自己不会使用类。还在学习中。
    现在用 queue (1)。
    但是发现日志文件如果是第二天的时候没法从头读取。晚上在学习下
    ryd994
        19
    ryd994  
       2017-01-28 06:19:55 +08:00
    这个需求为什么用线程?
    多线程访问数据库又不会快
    循环就行

    “再启动的线程等待第一个线程结束后再执行”这样是不对的
    考虑万一你运气不好,一连串的都慢了,就会有一堆在等,然后这个队就没有头了

    加锁,但是不阻塞,拿不到锁就退出,等别人做。
    qile1
        20
    qile1  
    OP
       2017-01-29 01:47:44 +08:00 via Android
    @ryd994 感觉我可能程序写的有点问题!把读取文件加锁后,如果上一程序在读完日志,开始处理数据插入工作,在有日志增加,检测到锁就退出会导致有数据无法读取到。处理数据这块不好加快速度,得读取具体指值,然后通过多次查询数据库信息比对转换后插入多个表
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1595 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:00 · PVG 01:00 · LAX 10:00 · JFK 13:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.