1

Cygwin のマルチプロセッシング モジュールからキューを作成しようとすると、奇妙な断続的なエラーが発生します。

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    multiprocessing.Queue()
  File "/usr/lib/python2.6/multiprocessing/__init__.py", line 213, in Queue
    return Queue(maxsize)
  File "/usr/lib/python2.6/multiprocessing/queues.py", line 37, in __init__
    self._rlock = Lock()
  File "/usr/lib/python2.6/multiprocessing/synchronize.py", line 117, in __init__
    SemLock.__init__(self, SEMAPHORE, 1, 1)
  File "/usr/lib/python2.6/multiprocessing/synchronize.py", line 49, in __init__
    sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
OSError: [Errno 17] File exists

これを再現するための最小限のコードは次のとおりです。

import multiprocessing

multiprocessing.Queue()

ただし、エラーは約 25% の確率でしか発生しません。

現在、この問題を「解決」するためにQueue、エラーが表示されなくなるまで s を継続的に作成する while ループがありますが、エラーが発生する理由を理解したいと思います。記載されているソース ファイルを調べてみましたが、c ソースまでさかのぼっても何の光も当てませんでした。

Windows 7 64ビットでCygwinからpython 2.6.7を実行しています。Cygwin からではなく、ネイティブの Windows python を介して cmd からこれを実行すると、問題は発生しません。

更新: ソースを詳しく見てみると、CreateSemaphore C 関数は "name" パラメーターを受け取るように見えます。この名前のセマフォが既に存在する場合は、エラーERROR_ALREADY_EXISTSがフラグされます。ただし、Modules/_multiprocessing/semaphore.c の python ソースでは、この関数は name パラメータなしで呼び出されるため、これは発生しないはずです。これは、cygwin のセマフォ実装の癖にすぎないと思います。

Edit2:私は今、そのようなセットアップを持っています:

import multiprocessing

for i in range(10):
    count = 0
    while True:
        try:
            q = multiprocessing.Queue()
            break
        except OSError as exc:
            if exc.errno == 17:
                count += 1
            else:
                raise # catch other errors, but this has never happened
    print "iterations %d" % count

私は奇妙な点に注意しました: Queue コンストラクターが失敗する回数は常に 3003 回以下であり、正確に 3000 回も頻繁に発生します。さらに、コンストラクターが一度成功すると、for ループの残りの繰り返しで再び失敗することはありません。

私はまだ困惑しています!gc.collect、time.sleep、キュー自体で close または del を呼び出してみましたが、これらのどれも影響を与えていないようです。これが実際にセマフォをクリーンアップするオペレーティングシステムに問題がある場合、システムコールを介してこれを「強制」する方法はありますか?

4

1 に答える 1

2

Cygwin python 2.6.8でも壊れています

$ python
Python 2.6.8 (unknown, Jun  9 2012, 11:30:32) 
[GCC 4.5.3] on cygwin

multiprocessing.futuresを使用して いるため、エラー (下記) が発生しますmultiprocessing.queue。残念!gevent の代替として使用することを望んでいました (gevent はモンキー パッチを使用するため)。

$ ./eg3
Traceback (most recent call last):
  File "./eg3", line 13, in <module>
    with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
  File "/usr/lib/python2.6/site-packages/concurrent/futures/process.py", line 275, in __init__
    EXTRA_QUEUED_CALLS)
  File "/usr/lib/python2.6/site-packages/multiprocessing-2.6.2.1-py2.6-cygwin-1.7.16-i686.egg/multiprocessing/__init__.py", line 219, in Queue
    return Queue(maxsize)
  File "/usr/lib/python2.6/site-packages/multiprocessing-2.6.2.1-py2.6-cygwin-1.7.16-i686.egg/multiprocessing/queues.py", line 37, in __init__
    self._rlock = Lock()
  File "/usr/lib/python2.6/site-packages/multiprocessing-2.6.2.1-py2.6-cygwin-1.7.16-i686.egg/multiprocessing/synchronize.py", line 117, in __init__
    SemLock.__init__(self, SEMAPHORE, 1, 1)
  File "/usr/lib/python2.6/site-packages/multiprocessing-2.6.2.1-py2.6-cygwin-1.7.16-i686.egg/multiprocessing/synchronize.py", line 49, in __init__
    sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
OSError: [Errno 17] File exists
于 2012-11-30T21:31:38.277 に答える