Saya ingin menjeda utas dengan python ketika fungsi lain dipanggil. Dalam kode di bawah ini, f2 memiliki prioritas lebih tinggi, dan f1 harus menunggu hingga selesai. Setelah membaca postingan ini saya mencoba ini:

import threading
import time

class c:
  def f1():
    for j in range(7):
      print ("f1")
      time.sleep(0.5)


def f2():
  with lock:
    for i in range(3):
      print(i)
      time.sleep(1)

lock = threading.Lock()
threading.Thread(target=c.f1).start()
f2()

Tapi hasilnya begini

f1
0
f1
1
f1
f1
2
f1
f1
f1

Sedangkan output yang diharapkan harus ini

f1
0
1
2
f1
f1
f1
f1
f1
f1

Apa yang salah? Jika saya menambahkan with lock di dalam f1 sebelum atau sesudah for saya mendapatkan hasil ini

f1
f1
f1
f1
f1
f1
f1
0
1
2

Yang sama-sama tidak diinginkan.

Juga harap dicatat bahwa struktur kode itu penting. Jika Anda menawarkan solusi, harap pertahankan struktur yang sama, artinya fungsi f1 di dalam kelas c dan sisanya dalam lingkup global. Hanya satu utas yang dibuat secara total.

Terima kasih

0
ErgiS 8 Agustus 2019, 16:56

1 menjawab

Jawaban Terbaik

Masalah Anda adalah Anda menggunakan kunci hanya di satu tempat - yang berarti tidak mengunci apa pun. Anda juga harus mendapatkan kunci di f1.

Pertimbangkan versi kode Anda ini:

import threading
import time

class c:
  def f1():
    for j in range(7):
      with lock:
           print ("f1")
      time.sleep(0.5)


def f2():
  with lock:
    for i in range(3):
      print(i)
      time.sleep(1)

lock = threading.Lock()
threading.Thread(target=c.f1).start()
f2()

Sekarang kita paksa f1 untuk berhenti dan menunggu kunci jika f2 sudah mendapatkannya. Apakah ini yang Anda coba capai?

Tentu saja tanpa pernyataan tidur hasilnya bisa apa saja - tidak ada jaminan berapa kali f1 Anda berhasil mengeksekusi sebelum f2 masuk dan mendapatkan kunci untuk keseluruhan loopnya.

Ini menjadi lebih rumit jika f1 dan f2 adalah fungsi "berat" dan Anda ingin memberi sinyal dari f2 kapan saja tanpa penundaan ke f1 "berhenti melakukan apa yang Anda lakukan sekarang". Kunci mungkin berfungsi jika ada loop tetapi jika misalnya ada panggilan IO yang panjang dalam proses, itu harus diselesaikan sebelum f1 merilis kunci untuk f2, yang berarti f2 akan memblokir dalam kasus ini.

Tanpa mengetahui kasus yang tepat ini hanya spekulasi.

2
Hannu 8 Agustus 2019, 14:31