Jadi saya ingin membuat proses menggunakan modul multiprosesor python, saya ingin itu menjadi bagian dari skrip yang lebih besar. (Saya juga menginginkan banyak hal lain darinya tetapi sekarang saya akan menerima ini)

Saya menyalin kode paling dasar dari dokumen multiproses dan memodifikasinya sedikit

Namun, semuanya di luar pernyataan if __name__ == '__main__': akan diulang setiap kali p.join() dipanggil.

Ini kode saya:

from multiprocessing import Process

data = 'The Data'
print(data)

# worker function definition
def f(p_num):
    print('Doing Process: {}'.format(p_num))

print('start of name == main ')

if __name__ == '__main__':
    print('Creating process')
    p = Process(target=f, args=(data,))
    print('Process made')
    p.start()
    print('process started')
    p.join()
    print('process joined')

print('script finished')

Inilah yang harapkan:

The Data
start of name == main 
Creating process
Process made
process started
Doing Process: The Data
process joined
script finished

Process finished with exit code 0

Inilah kenyataan:

The Data
start of name == main 
Creating process
Process made
process started
The Data                         <- wrongly repeated line
start of name == main            <- wrongly repeated line
script finished                  <- wrongly executed early line
Doing Process: The Data
process joined
script finished

Process finished with exit code 0

Saya tidak yakin apakah ini disebabkan oleh pernyataan if atau p.join() atau sesuatu yang lain dan dengan ekstensi mengapa ini terjadi. Bisakah seseorang menjelaskan apa yang menyebabkan ini dan mengapa?

Untuk kejelasan karena beberapa orang tidak dapat meniru masalah saya tetapi saya punya; Saya menggunakan Pusat Data Windows Server 2012 R2 dan saya menggunakan python 3.5.3.

6
Harry de winton 9 Agustus 2017, 16:23

2 jawaban

Jawaban Terbaik

Cara Multiprocessing bekerja dengan Python sedemikian rupa sehingga setiap anak memproses import< /em> skrip induk. Dalam Python, saat Anda mengimpor skrip, semua yang tidak ditentukan dalam suatu fungsi akan dieksekusi. Seperti yang saya pahami, __name__ diubah pada impor skrip (Periksa jawaban SO ini di sini untuk pemahaman yang lebih baik), yang berbeda dari jika Anda menjalankan skrip pada baris perintah secara langsung, yang akan menghasilkan __name__ == '__main__'. Impor ini menghasilkan __name__ tidak sama dengan '__main__', itulah sebabnya kode dalam if __name__ == '__main__': tidak dieksekusi untuk subproses Anda.

Apa pun yang Anda tidak ingin dieksekusi selama panggilan subproses harus dipindahkan ke bagian if __name__ == '__main__': kode Anda, karena ini hanya akan berjalan untuk proses induk, yaitu skrip yang Anda jalankan pada awalnya.

Semoga ini bisa membantu sedikit. Ada beberapa sumber daya lain di sekitar Google yang menjelaskan hal ini dengan lebih baik jika Anda melihat-lihat. Saya menautkan sumber Python resmi untuk modul multiprosesor, dan saya sarankan Anda memeriksanya.

9
Peter 9 Agustus 2017, 15:36

Menjelajahi topik saya mengalami masalah banyak modul. untuk membuatnya berfungsi per di atas saya harus:

  • letakkan semua impor dalam suatu fungsi (penginisialisasi ())
  • kembalikan semua impor sebagai objek dalam panggilan ke fungsi initializer()
  • referensi objek-objek itu dalam definisi dan panggilan ke fungsi yang tersisa di modul saya

Modul contoh di bawah ini menjalankan beberapa pendekatan klasifikasi pada dataset yang sama secara paralel:

print("I am being run so often because: https://stackoverflow.com/questions/45591987/multi-processing-code-repeatedly-runs")

def initializer():
    from sklearn import datasets

    iris = datasets.load_iris()
    x = iris.data
    y = iris.target    

    from sklearn.preprocessing import StandardScaler as StandardScaler
    from sklearn.metrics import accuracy_score
    from sklearn.linear_model import Perceptron
    from sklearn.linear_model import LogisticRegression
    from sklearn.pipeline import Pipeline
    import multiprocessing as mp
    from multiprocessing import Manager

    results = [] # for some reason it needs to be defined before the if __name__ = __main__

    return x, y, StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline, mp, Manager, results

def perceptron(x,y,results, StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline):
    scaler = StandardScaler()
    estimator = ["Perceptron", Perceptron(n_iter=40, eta0=0.1, random_state=1)]

    pipe =  Pipeline([('Scaler', scaler),
                      ('Estimator', estimator[1])])

    pipe.fit(x,y)

    y_pred_pipe = pipe.predict(x)
    accuracy = accuracy_score(y, y_pred_pipe)
    result = [estimator[0], estimator[1], pipe, y_pred_pipe, accuracy]
    results.append(result)
    print(estimator[0], "Accuracy: ",accuracy)
    return results

def logistic(x,y,results,StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline):
    scaler = StandardScaler()
    estimator = ["LogisticRegression", LogisticRegression(C=100.0, random_state=1)]

    pipe =  Pipeline([('Scaler', scaler),
                      ('Estimator', estimator[1])])

    pipe.fit(x,y)

    y_pred_pipe = pipe.predict(x)
    accuracy = accuracy_score(y, y_pred_pipe)
    result = [estimator[0], estimator[1], pipe, y_pred_pipe, accuracy]
    #results = []
    results.append(result)
    print(estimator[0], "Accuracy: ",accuracy)
    return results

def parallel(x,y,results,StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline):
    with Manager() as manager:

        tasks = [perceptron, logistic,]
        results = manager.list() 
        procs = []
        for task in tasks:
            proc = mp.Process(name=task.__name__, target=task, args=(x,y,results,StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline))
            procs.append(proc)
            print("done with check 1")
            proc.start()
            print("done with check 2")

        for proc in procs:
            print("done with check 3")
            proc.join()
            print("done with check 4")

        results = list(results)
        print("Within WITH")
        print(results)

    print("Within def")
    print(results)
    return results 

if __name__ == '__main__':
    __spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"

    x, y, StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline, mp, Manager, results = initializer()

    results = parallel(x,y,results,StandardScaler, accuracy_score, Perceptron, LogisticRegression, Pipeline)

    print("Outside of def")
    print(type(results))
    print(len(results))

    print(results[1]) # must be within IF as otherwise does not work ?!?!?!?

    cpu_count = mp.cpu_count()
    print("CPUs: ", cpu_count)
0
Nick 30 Desember 2018, 00:48