de-vraag
  • Pertanyaan
  • Tag
  • Pengguna
Notifikasi
Imbalan
Registrasi
Setelah Anda mendaftar, Anda akan diberitahu tentang balasan dan komentar untuk pertanyaan Anda.
Gabung
Jika Anda sudah memiliki akun, masuk untuk memeriksa pemberitahuan baru.
Akan ada hadiah untuk pertanyaan, jawaban, dan komentar tambahan.
Lebih
Sumber
Sunting
Mauro Midolo
Mauro Midolo
Question

Menggunakan variabel global dengan benang

Bagaimana cara berbagi variabel global dengan benang?

Saya Python contoh kode ini:

from threading import Thread
import time
a = 0  #global variable

def thread1(threadname):
    #read variable "a" modify by thread 2

def thread2(threadname):
    while 1:
        a += 1
        time.sleep(1)

thread1 = Thread( target=thread1, args=("Thread-1", ) )
thread2 = Thread( target=thread2, args=("Thread-2", ) )

thread1.join()
thread2.join()

Saya don't tahu bagaimana untuk mendapatkan dua benang untuk berbagi satu variabel.

69 2013-11-05T13:50:46+00:00 5
 codeforester
codeforester
Pertanyaan edit 27 Oktober 2018 в 10:32
Pemrograman
multithreading
python
global-variables
Solution / Answer
 chepner
chepner
5 November 2013 в 2:01
2013-11-05T14:01:50+00:00
Lebih
Sumber
Sunting
#22719190

Anda hanya perlu untuk menyatakan a sebagai global di thread2, sehingga anda tidak't memodifikasi sebuah a itu adalah lokal untuk fungsi itu.

def thread2(threadname):
    global a
    while True:
        a += 1
        time.sleep(1)

Di thread1, anda don't perlu melakukan sesuatu yang khusus, asalkan anda don't mencoba untuk mengubah nilai dari a (yang akan membuat variabel lokal bahwa bayangan yang global; menggunakan global jika anda perlu)>

def thread1(threadname):
    #global a       # Optional if you treat a as read-only
    while a < 10:
        print a
78
0
 val
val
5 November 2013 в 2:11
2013-11-05T14:11:13+00:00
Lebih
Sumber
Sunting
#22719191

Dalam fungsi:

a += 1

akan diterjemahkan oleh compiler sebagai menetapkan ke => Membuat variabel lokal a, yang adalah bukan apa yang anda inginkan. Mungkin akan gagal dengan yang tidak diinisialisasi kesalahan sejak (lokal) yang memang belum diinisialisasi:

>>> a = 1
>>> def f():
...     a += 1
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment

Anda mungkin mendapatkan apa yang anda inginkan dengan (sangat disukai, dan untuk alasan yang baik) global kata kunci, seperti:

>>> def f():
...     global a
...     a += 1
... 
>>> a
1
>>> f()
>>> a
2

Pada umumnya namun, anda harus avoid menggunakan variabel global yang menjadi sangat cepat keluar dari tangan. Dan hal ini terutama berlaku untuk program multithreaded, di mana anda don't memiliki mekanisme sinkronisasi untuk anda thread1 untuk tahu kapan a telah dimodifikasi. Singkatnya: benang ribet, dan anda tidak bisa berharap untuk memiliki pemahaman intuitif dari urutan di mana peristiwa terjadi ketika dua (atau lebih) benang bekerja pada nilai yang sama. Bahasa, compiler, OS, prosesor... SEMUA bisa memainkan peran, dan memutuskan untuk mengubah urutan operasi untuk kecepatan, kepraktisan, atau alasan lain.

Cara yang tepat untuk hal semacam ini adalah dengan menggunakan Python alat berbagi (kunci dan teman-teman), atau lebih baik, berkomunikasi data melalui Antri bukannya berbagi itu, misalnya seperti ini:

from threading import Thread
from queue import Queue
import time

def thread1(threadname, q):
    #read variable "a" modify by thread 2
    while True:
        a = q.get()
        if a is None: return # Poison pill
        print a

def thread2(threadname, q):
    a = 0
    for _ in xrange(10):
        a += 1
        q.put(a)
        time.sleep(1)
    q.put(None) # Poison pill

queue = Queue()
thread1 = Thread( target=thread1, args=("Thread-1", queue) )
thread2 = Thread( target=thread2, args=("Thread-2", queue) )

thread1.start()
thread2.start()
thread1.join()
thread2.join()
 CharlesB
CharlesB
Jawaban edit 23 November 2018 в 1:26
45
0
Jason Pan
Jason Pan
15 Januari 2019 в 6:04
2019-01-15T06:04:17+00:00
Lebih
Sumber
Sunting
#22719193

Kunci yang harus dipertimbangkan untuk digunakan, seperti threading.Lock. Lihat lock-benda untuk info lebih lanjut.

Jawaban yang diterima DAPAT mencetak 10 oleh thread1, yang adalah bukan apa yang anda inginkan. Anda dapat menjalankan kode berikut untuk memahami bug lebih mudah.

def thread1(threadname):
    while True:
      if a % 2 and not a % 2:
          print "unreachable."

def thread2(threadname):
    global a
    while True:
        a += 1

Menggunakan kunci yang bisa melarang berubah dari a sambil membaca lebih dari satu kali:

def thread1(threadname):
    while True:
      lock_a.acquire()
      if a % 2 and not a % 2:
          print "unreachable."
      lock_a.release()

def thread2(threadname):
    global a
    while True:
        lock_a.acquire()
        a += 1
        lock_a.release()

Jika benang menggunakan variabel untuk waktu yang lama, mengatasi ke variabel lokal pertama adalah pilihan yang baik.

4
0
Krista  M Hill
Krista M Hill
21 Februari 2019 в 5:27
2019-02-21T17:27:26+00:00
Lebih
Sumber
Sunting
#22719194

Terima kasih banyak Jason Pan untuk menunjukkan bahwa metode. Yang thread1 jika pernyataan ini tidak atom, sehingga sementara pernyataan yang dijalankan, it's mungkin untuk thread2 untuk mengganggu thread1, memungkinkan non-dicapai kode untuk dicapai. I've diselenggarakan ide-ide dari sebelum posting ke program demonstrasi (di bawah ini) bahwa saya berlari dengan Python 2.7.

Dengan beberapa pemikiran analisis I'm yakin kita bisa mendapatkan wawasan lebih lanjut, tapi untuk sekarang saya pikir itu's penting untuk menunjukkan apa yang terjadi ketika non-perilaku atom memenuhi threading.

# ThreadTest01.py - Demonstrates that if non-atomic actions on
# global variables are protected, task can intrude on each other.
from threading import Thread
import time

# global variable
a = 0; NN = 100

def thread1(threadname):
    while True:
      if a % 2 and not a % 2:
          print("unreachable.")
    # end of thread1

def thread2(threadname):
    global a
    for _ in range(NN):
        a += 1
        time.sleep(0.1)
    # end of thread2

thread1 = Thread(target=thread1, args=("Thread1",))
thread2 = Thread(target=thread2, args=("Thread2",))

thread1.start()
thread2.start()

thread2.join()
# end of ThreadTest01.py

Seperti yang diperkirakan, dalam menjalankan contoh, "terjangkau" kadang-kadang kode ini benar-benar tercapai, memproduksi output.

Hanya untuk menambahkan, ketika saya memasukkan kunci memperoleh/rilis pasangan ke thread1 saya menemukan bahwa kemungkinan memiliki "terjangkau" pesan cetak sangat berkurang. Untuk melihat pesan yang saya mengurangi waktu tidur untuk 0.01 sec dan peningkatan NN ke 1000.

Dengan kunci memperoleh/rilis pasangan di thread1 saya didn't berharap untuk melihat pesan sama sekali, tapi itu's ada. Setelah aku dimasukkan kunci memperoleh/rilis pasangan juga ke thread2, pesan tidak lagi muncul. Di belakang rambu, kenaikan pernyataan di thread2 mungkin juga non-atom.

Krista  M Hill
Krista M Hill
Jawaban edit 22 Februari 2019 в 4:14
3
0
 visoft
visoft
26 September 2018 в 9:45
2018-09-26T09:45:11+00:00
Lebih
Sumber
Sunting
#22719192

Nah, berjalan contoh:

PERINGATAN! JANGAN PERNAH LAKUKAN INI DI RUMAH/BEKERJA! Hanya di dalam kelas ;)

Menggunakan semaphore, variabel bersama, dll. untuk menghindari kondisi terburu-buru.

from threading import Thread
import time

a = 0  # global variable

def thread1(threadname):
    global a
    for k in range(100):
        print("{} {}".format(threadname, a))
        time.sleep(0.1)
        if k == 5:
            a += 100

def thread2(threadname):
    global a
    for k in range(10):
        a += 1
        time.sleep(0.2)

thread1 = Thread(target=thread1, args=("Thread-1",))
thread2 = Thread(target=thread2, args=("Thread-2",))

thread1.start()
thread2.start()

thread1.join()
thread2.join()

dan output:

Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 2
Thread-1 3
Thread-1 3
Thread-1 104
Thread-1 104
Thread-1 105
Thread-1 105
Thread-1 106
Thread-1 106
Thread-1 107
Thread-1 107
Thread-1 108
Thread-1 108
Thread-1 109
Thread-1 109
Thread-1 110
Thread-1 110
Thread-1 110
Thread-1 110
Thread-1 110
Thread-1 110
Thread-1 110
Thread-1 110

Jika waktunya tepat, a += 100 operasi yang akan dilewati:

Prosesor mengeksekusi pada T a+100 dan mendapat 104. Tapi itu berhenti, dan melompat ke thread berikutnya Di sini, Pada T+1 mengeksekusi +1 dengan nilai a, a == 4. Jadi menghitung 5. Melompat kembali (pada T+2), benang 1, dan menulis a=104 dalam memori. Sekarang kembali pada benang 2, waktu adalah T+3 dan menulis a=5 dalam memori. Voila! Berikutnya cetak instruksi ini akan cetak 5 bukan dari 104.

SANGAT bug jahat untuk direproduksi dan tertangkap.

1
0
Related communities 6
Python Indonesia
Python Indonesia
24 686 pengguna
Programmer Python Indonesia. Group ini dikelola oleh sejumlah admin. Baca pesan tersemat / pinned message: https://t.me/pythonID/217588
Buka telegram
Indonesian Python Warriors
Indonesian Python Warriors
1 462 pengguna
Di grup ini tidak ada kewajiban untuk menggunakan username dan foto. Yang tidak boleh adalah spamming. Gak boleh baper, kalau nanya yang bener, eror jangan difoto pake HP, gunakan screenshot, code copas ke pastebin.com lalu share link ke sini.
Buka telegram
Python-ID Jogja
Python-ID Jogja
962 pengguna
Buka telegram
BASIC PYTHON INDONESIA
BASIC PYTHON INDONESIA
214 pengguna
Buka telegram
Python Newbie Indonesia
Python Newbie Indonesia
180 pengguna
Peraturan grup Python Newbie 🌻Dilarang spam 🌻Dilarang menggunakan bahasa kasar 🌻Dilarang beriklan di grup tanpa seizin admin Beberapa video dasar python dapat diliat melalui channel youtube juan aditya Jangan lupa untuk subscribe ya🙏
Buka telegram
PythonWealth Indonesia 🇮🇩
PythonWealth Indonesia 🇮🇩
29 pengguna
Buka telegram
Tambahkan pertanyaan
Kategori
Semua
Teknologi
Budaya / Rekreasi
Kehidupan / Seni
Ilmu Pengetahuan
Profesional
Bisnis
Pengguna
Semua
Baru
Populer
1
Asilbek Qadamboyev
Terdaftar 6 jam yang lalu
2
Akshit Mehta
Terdaftar 2 hari yang lalu
3
me you
Terdaftar 5 hari yang lalu
4
Никита иванов
Terdaftar 1 minggu yang lalu
5
Alex1976G_06
Terdaftar 1 minggu yang lalu
ID
JA
RU
© de-vraag 2022
Sumber
stackoverflow.com
di bawah lisensi cc by-sa 3.0 dengan atribusi