7

アプリケーションに必要なすべてのリソース (主に画像) をメモリにロードするクラスがあります。

次に、複数のスレッドがこのクラスを介してこれらのリソースにアクセスする必要があります。すべてのインスタンスがすべてのリソースをリロードするのは望ましくないため、Singleton パターンを使用することにしました。私はこのようにしました:

class DataContainer(object):
    _instance = None
    _lock = threading.Lock()
    _initialised = True

    def __new__(cls, *args, **kwargs):
        with cls._lock:
            if not cls._instance:
                cls._initialised = False
                cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self, map_name = None):

        # instance has already been created
        if self._initialised:
            return

        self._initialised = True

        # load images

複数のスレッドを使用していない限り、これは正常に機能します。ただし、複数のスレッドを使用すると、すべてのスレッドが異なるインスタンスを持ちます。したがって、4 つのスレッドを使用して、それぞれが新しいインスタンスを作成します。すべてのスレッドがこのクラスの同じインスタンスを使用するようにしたいので、リソースは一度だけメモリにロードされます。

また、クラスが定義されているのと同じモジュールでこれを実行しようとしましたが、クラス定義の外側にありました。

def getDataContainer():
    global dataContainer
    return dataContainer

dataContainer = DataContainer()

ただし、すべてのスレッドには独自のインスタンスがあります。

私はPythonを初めて使用します。これが間違ったアプローチである場合は、教えてください。助けていただければ幸いです

4

1 に答える 1

11

@Will のコメントを拡張すると、「共有オブジェクト」が親によって作成され、各スレッドに渡された場合、すべてのスレッドが同じオブジェクトを共有します。

(プロセスについては、変更を含む状態の共有を直接サポートするmultiprocessing.Managerクラスを参照してください。)

import threading, time


class SharedObj(object):
    image = 'beer.jpg'


class DoWork(threading.Thread):
    def __init__(self, shared, *args, **kwargs):
        super(DoWork,self).__init__(*args, **kwargs)
        self.shared = shared

    def run(self):
        print threading.current_thread(), 'start'
        time.sleep(1)
        print 'shared', self.shared.image, id(self.shared)
        print threading.current_thread(), 'done'


myshared = SharedObj()
threads = [ DoWork(shared=myshared, name='a'), 
            DoWork(shared=myshared, name='b')
]
for t in threads:
    t.start()
for t in threads:
    t.join()
print 'DONE'

出力:

<DoWork(a, started 140381090318080)> start
<DoWork(b, started 140381006067456)> start
shared beer.jpg shared140381110335440
 <DoWork(b, started 140381006067456)> done
beer.jpg 140381110335440
<DoWork(a, started 140381090318080)> done
DONE

スレッド ID は異なりますが、どちらもSharedObj440 で終わるメモリ アドレスで同じインスタンスを使用していることに注意してください。

于 2014-05-31T19:12:30.880 に答える