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

python多线程任务冲突

  •  
  •   mac2man · 2013-07-01 22:00:31 +08:00 · 4468 次点击
    这是一个创建于 4190 天前的主题,其中的信息可能已经有所发展或是发生改变。
    python下os.system使用shell脚本处理目录下的一些文件,shell分了几个步骤,用了多线程,当上个线程还未未处理完数据,下一个线程已经启动,同样处理了此文件,造成了一些冲突,

    贴上这部分代码:
    def save(fn, ts):
    try:
    print 'save', fn, '...', ts
    s = os.path.basename(fn)
    if s[-3:] == '.gz':
    is_gz = True
    s = s[:-3]
    else:
    is_gz = False
    if s[:3] == 'dx.':
    if is_gz:
    dt = s.split('.')[4][:8]
    p = DST_DIANXIN + dt + '/'
    os.system('mkdir -p ' + p)
    dx_fn = p + s + '.txt'
    dx_tmp = p + s + '.new'
    print 'zcat', fn, '-->', dx_fn
    os.system('zcat %s > %s; mv -f %s %s; rm -rf %s' % (fn, dx_tmp, dx_tmp, dx_fn, fn))
    # os.remove(fn)

    while True:
    if os.path.exists(SRC + 'stopping'):
    break
    rpts = glob.glob(SRC + '*.gz')
    rpts.sort()
    for fn in rpts:
    fn2 = fn
    if os.path.exists(fn2):
    ts = len(threading.enumerate())
    while ts > MAXTHREADS:
    ts = len(threading.enumerate())
    time.sleep(0.2)
    threading.Timer(0.2, save, args=(fn2,ts)).start()
    time.sleep(1)
    10 条回复    1970-01-01 08:00:00 +08:00
    BOYPT
        1
    BOYPT  
       2013-07-01 22:10:49 +08:00
    加锁。
    tsinglux
        2
    tsinglux  
       2013-07-01 22:24:38 +08:00
    只会最基本的mutex操作,每次打开一个文件就设置一个mutex=1,其他线程打开文件时就检测对应文件mutex是否为0,是就设置为1并打开操作,不是就sleep,然后再次查询。
    sykp241095
        3
    sykp241095  
       2013-07-01 22:29:37 +08:00
    也可以不用锁。

    1,在启动其他线程前,记录一共有多少个文件,放在一个list里,比如有30个;
    2, 将thread的名字设为有规律的,如thread-1, thread-2, thread-3;
    3,thread-1处理前10个,thread-2处理中间10个,thread-3处理最后10个。
    mac2man
        4
    mac2man  
    OP
       2013-07-01 22:40:41 +08:00
    @sykp241095 所以你的意思根据文件数创建线程数
    你看我代码里,最后是删除掉这个文件,关键就是在这里,文件很大
    等下次再次获取有多少个文件时,某个文件可能还存在,这样就冲突了啊
    mac2man
        5
    mac2man  
    OP
       2013-07-01 22:43:51 +08:00
    @BOYPT
    @tsinglux
    加锁肯定是个很好的办法,我也是在想是否可以生成一个对应的fin文件,取文件时筛选掉这部分

    我是在考虑线程中是否就能很好解决掉这个问题了,比如可以获知是否有其他进程正在处理这个文件
    BOYPT
        6
    BOYPT  
       2013-07-02 08:50:15 +08:00
    你贴成这样还指望有人去看你代码。
    sykp241095
        7
    sykp241095  
       2013-07-02 10:13:15 +08:00
    事实上,我也没看lz的代码。

    其实可以用各种线程安全的queue,将所有文件组织成一个queue,比如threading.deque,然后每个线程都可以去pop/shift,这样也不用加锁。
    mac2man
        8
    mac2man  
    OP
       2013-07-02 10:51:12 +08:00
    @sykp241095
    @BOYPT 唉。。。v2ex贴上来就这样了
    问题已经解决了,挺简单的,那就是先改个名,哈哈哈
    qdcanyun
        9
    qdcanyun  
       2013-07-02 15:27:29 +08:00
    恩 没看代码
    同意@sykp241095 的方案 组织成queue 这样你就不用手动加锁了
    Queue是线程安全的
    ma6174
        10
    ma6174  
       2013-07-02 15:44:13 +08:00
    Queue +1
    任务队列,生产者消费者模式就挺好,保证不会乱的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1258 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:00 · PVG 08:00 · LAX 16:00 · JFK 19:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.