multithreading - Shared variables in Python -
i trying create multiple threads of bot
, share variables, failing miserably in getingt shared variables work.
here code:
import requests import sys import threading import signal import time class bot(threading.thread): terminate = false #def __init__(self): # threading.thread.__init__(self) # self.terminate = false def getcode(): code_lock.acquire() work_code = code try: code += 1 finally: code_lock.release() return work_code def checkcode(code): try: #if(code % 1000000 == 0): print("code "+str(code)+" being checked...\n") html = requests.get(url+str(code)) html.encoding = 'utf-8' return not 'page not found' in html.text except requests.exceptions.connectionerror: print("connection error! retrying...\n") time.sleep(0.5) except keyboardinterrupt: logcode(code) sys.exit() def storecode(code): file_lock.acquire() try: file.write(code+'\n') finally: file_lock.release() def logcode(code): log_lock.acquire() try: log.write(code+'\n') finally: log_lock.release() #def run(self): # global bots # global url # global file # global log # global code_lock # global file_lock # global log_lock while(not terminate): code = getcode() if(checkcode(code)): storecode(code) logcode(code) def main(code = 0, threads = 16): #bots = [threading.thread(target=bot) bot in range(threads)] bots = [] url = 'https://test.ing/codes/' file = open("valid-codes.txt", "a") log = open("log.txt", "a") code_lock = threading.lock() file_lock = threading.lock() log_lock = threading.lock() def signal_handler(signal, frame): print('exiting...\n') log_lock.acquire() try: log.write("\n\n"+str(time.strftime("%y-%m-%d %h:%m:%s", time.gmtime()))+"\n") finally: log_lock.release() bot in bots: bot.terminate = true bot in bots: bot.join() sys.exit(0) #for bot in bots: # bot.start() in range(threads): t = bot() bots.append(t) t.start() signal.signal(signal.sigint, signal_handler) while true: signal.pause() main(736479509787350, 1)
with code error:
traceback (most recent call last): file "bot.py", line 7, in
class bot(threading.thread): file "bot.py", line 59, in bot code = getcode() file "bot.py", line 14, in getcode code_lock.acquire() nameerror: name 'code_lock' not defined
i don't know if should override run(self)
method of bot
, when tried never ran method run
, receive same error threads created: int
not callable (and can't see can possibly using int object).
additionaly don't know if handling correctly exit signal keyboard, can see trying deal using terminate
variable, don't think problem...
one last thing, connectionerror
exception not being appropriately handled, it's saying "retrying...", in fact not retry, aware of , should ok, i'll fix latter.
worth mentioning i'm not used deal multi-threading , when deal it, in c or c++.
edit
i can make code work using global variables, not want that, prefer avoid using globals. attempts of passing variables directly instances of class bot
or passing data-object weren't successful far, whenever pass variables or auxiliar object bot
unable access them attributes using self.
, without self.
python claims variable not defined.
here updated code, without success yet:
import requests import sys import threading import signal import time class shared: def __init__(self, code, url, file, log, code_lock, file_lock, log_lock): self.code = code self.url = url self.file = file self.log = log self.code_lock = code_lock self.file_lock = file_lock self.log_lock = log_lock class bot(threading.thread): def __init__(self, data): threading.thread.__init__(self) self.terminate = false self.data = data @classmethod def getcode(self): self.data.code_lock.acquire() work_code = self.data.code try: self.data.code += 1 finally: self.data.code_lock.release() return work_code @classmethod def checkcode(self, work_code): try: #if(code % 1000000 == 0): print("code "+str(work_code)+" being checked...\n") html = requests.get(self.data.url+str(work_code)) html.encoding = 'utf-8' return not 'page not found' in html.text except requests.exceptions.connectionerror: print("connection error! retrying...\n") time.sleep(0.5) except keyboardinterrupt: self.logcode(work_code) sys.exit() @classmethod def storecode(self, work_code): self.data.file_lock.acquire() try: self.data.file.write(work_code+'\n') finally: self.data.file_lock.release() @classmethod def logcode(self, work_code): self.data.log_lock.acquire() try: self.data.log.write(work_code+'\n') finally: self.data.log_lock.release() @classmethod def run(self): while(not self.terminate): work_code = self.getcode() if(self.checkcode(work_code)): self.storecode(work_code) self.logcode(work_code) def main(code = 0, threads = 16): #bots = [threading.thread(target=bot) bot in range(threads)] bots = [] url = 'https://www.test.ing/codes/' file = open("valid-codes.txt", "a") log = open("log.txt", "a") code_lock = threading.lock() file_lock = threading.lock() log_lock = threading.lock() data = shared(code, url, file, log, code_lock, file_lock, log_lock) def signal_handler(signal, frame): print('exiting...\n') log_lock.acquire() try: log.write("\n\n"+str(time.strftime("%y-%m-%d %h:%m:%s", time.gmtime()))+"\n") finally: log_lock.release() bot in bots: bot.terminate = true bot in bots: bot.join() sys.exit(0) #for bot in bots: # bot.start() in range(threads): t = bot(data) bots.append(t) t.start() signal.signal(signal.sigint, signal_handler) while true: signal.pause() main(736479509787350, 4)
yet, working code global variables:
import requests import sys import threading import signal import time code = 736479509787350 url = 'https://www.test.ing/codes/' file = open("valid-codes.txt", "a") log = open("log.txt", "a") code_lock = threading.lock() file_lock = threading.lock() log_lock = threading.lock() terminate = false class bot(threading.thread): def __init__(self): threading.thread.__init__(self) @classmethod def getcode(self): global code code_lock.acquire() work_code = code try: code += 1 finally: code_lock.release() return work_code @classmethod def checkcode(self, work_code): try: if(code % 1000000 == 0): print("code "+str(work_code)+" being checked...\n") html = requests.get(url+str(work_code)) html.encoding = 'utf-8' if(not 'page not found' in html.text): time.sleep(0.5) html = requests.get(url+str(work_code)+":999999999") html.encoding = 'utf-8' return 'page not found' in html.text except requests.exceptions.connectionerror: #print("connection error! retrying...\n") time.sleep(1) return self.checkcode(work_code) except keyboardinterrupt: self.logcode(work_code) sys.exit() @classmethod def storecode(self, work_code): global file_lock global file file_lock.acquire() try: file.write(str(work_code)+'\n') finally: file_lock.release() @classmethod def logcode(self, work_code): global log_lock global log log_lock.acquire() try: log.write(str(work_code)+'\n') finally: log_lock.release() @classmethod def run(self): global terminate while(not terminate): work_code = self.getcode() if(self.checkcode(work_code)): print("code "+str(work_code)+" valid code!\n") self.storecode(work_code) self.logcode(work_code) def main(threads = 16): #bots = [threading.thread(target=bot) bot in range(threads)] bots = [] #url = 'https://www.facebook.com/leticia.m.demenezes/posts/' #file = open("valid-codes.txt", "a") #log = open("log.txt", "a") #code_lock = threading.lock() #file_lock = threading.lock() #log_lock = threading.lock() def signal_handler(signal, frame): global terminate print('exiting...\n') log_lock.acquire() try: log.write("\n\n"+str(time.strftime("%y-%m-%d %h:%m:%s", time.gmtime()))+"\n") finally: log_lock.release() terminate = true bot in bots: bot.join() sys.exit(0) #for bot in bots: # bot.start() in range(threads): t = bot() bots.append(t) t.start() signal.signal(signal.sigint, signal_handler) while true: signal.pause() main()
you make code_lock
global you're trying do, why not pass each bot
class?
t = bot(code_lock)
next create constructor class:
class bot(threading.thread): def __init__(self, code_lock): threading.thread.__init__(self) self.code_lock = code_lock
now, whenever try use code_lock
inside bot
class, prefix self
(self.code_lock
).
if insist on using global variables, global
keyword.
Comments
Post a Comment