Threading with Random wrong result - python-3.x

When using threading with random.shuffle get wrong result from a list.
There are values missing and other duplicated.
Tried use numpy but get the same problem.
#!/usr/bin/python3 -tt
import random
from threading import Thread
class Th(Thread):
def __init__ (self, num, c):
Thread.__init__(self)
self.c = c
self.num = num
def run(self):
random.shuffle(self.c)
for self.i in self.c:
print (str(self.num) + ' - ' + self.i)
def main():
with open ('file.txt', 'rU') as cmddb:
c = [ cmd.strip() for cmd in cmddb]
cmddb.close()
print ('ref:')
for i in c:
print (i)
print ('----')
thread_number=0
for i in range(0,5):
thread = Th(thread_number,c)
thread.start()
thread_number += 1
if __name__ == '__main__':
main()
#################################3
Result:
file.txt:
ref:
10
20
----
0 - 20 <========
1 - 10
1 - 20
0 - 20 <========= duplicated / missimg 10
3 - 20 <=
3 - 20 <= again
4 - 10
2 - 10
4 - 20
2 - 20
Problem occur some times. Other times it run ok.

This happens because the list c is the same list for all threads. So in some cases, some thread prints the first element of c, for example 10, and before it prints the second element, another thread called shuffle on c. if the order of the values in c has changed, the second element is now 10, so it will be printed again. To avoid it, give every thread a different copy of c:
change: thread = Th(thread_number,c) to thread = Th(thread_number, c[:])

Related

With this code, one of the hidden tc shows runtime error. I have used try-except in the main block but still the testcase fails by same error

I_have to_check_whether_the_elements_of_qarr_is_in_tarr,if_so_print_Yes_else_print_No
tarr_is_a_hashmap_while_qarr_is_a_list_object
every-test case passed except one, that shows runtime-error
I tried with try: take input except: pass, but still the problem exists
below is my approach. Please feel free to help.
s is total no of elements starting from 1
inputs:
6 4 4
1
3
4
6
1
2
5
Output
N
Y
Y
N
import sys
import os
#function
def hall(qarr,tarr,q,s):
if q==0:
for i in range(s):
print("N")
elif len(tarr)==0:
for i in range(q):
print("Y")
else:
for i in range(q):
if qarr[i] in tarr.keys():
if tarr[qarr[i]]==1:
print("N")
else:
print("Y")
#input_section
try:
k=list(map(int,input().split()))
s=k[0]
t=k[1]
q=k[2]
#creating_a_hashmap
tarr={}
for i in range(t):
h=int(input())
if h not in tarr.keys():
tarr[h]=1
else:
tarr[h]+=1
#creating_a_list
qarr=[]
for i in range(q):
h=int(input())
qarr.append(h)
#calling_the_function
hall(qarr,tarr,q,s)
except:
pass
#function_ended

Threading on python with time.sleep

I'm struggling to understand this example from a PyCon talk (link to code example)
import threading, time, random
##########################################################################################
# Fuzzing is a technique for amplifying race condition errors to make them more visible
FUZZ = True
def fuzz():
if FUZZ:
time.sleep(random.random())
###########################################################################################
counter = 0
def worker():
'My job is to increment the counter and print the current count'
global counter
fuzz()
oldcnt = counter
fuzz()
counter = oldcnt + 1
fuzz()
print('The count is %d' % counter, end='')
fuzz()
print()
fuzz()
print('---------------', end='')
fuzz()
print()
fuzz()
print('Starting up')
fuzz()
for i in range(10):
threading.Thread(target=worker).start()
fuzz()
print('Finishing up')
fuzz()
The above would print something like:
Starting up
The count is 1The count is 2The count is 2The count is 2
---------------The count is 3
---------------The count is 4
---------------
---------------The count is 4
The count is 5------------------------------
Finishing up
The count is 5
------------------------------
The count is 6---------------
---------------
What I don't understand about this is why sometimes, when a thread is put to sleep it continues from where it left off and other times it stops and starts the next iteration.
EDIT:
I clearly missed the for loop...
All the threads run to completion. That's the point of the lesson. When multiple threads access the same variable simultaneously, you can get unexpected results.
I've modified the code slightly to print less distracting stuff and also a thread id. I think this should help clarify what is happening:
import threading, time, random
##########################################################################################
# Fuzzing is a technique for amplifying race condition errors to make them more visible
FUZZ = True
def fuzz():
if FUZZ:
delay = random.random()
time.sleep(delay)
return delay
###########################################################################################
counter = 0
def worker(id):
'My job is to increment the counter and print the current count'
global counter
fuzz()
oldcnt = counter
delay = fuzz()
counter = oldcnt + 1
print('%d> After %s seconds, the count is %d -> %d' % (id, delay, oldcnt, counter))
print('Starting up')
fuzz()
for i in range(10):
threading.Thread(target=worker, args=(i,)).start()
fuzz()
print('Finishing up')
fuzz()
Example output (because of the randomness, this will change each run):
Starting up
0> After 0.7350378311578315 seconds, the count is 0 -> 1
2> After 0.1785671063273092 seconds, the count is 1 -> 2
1> After 0.8294767498326181 seconds, the count is 0 -> 2
3> After 0.5901283670333175 seconds, the count is 1 -> 3
4> After 0.14964432977752684 seconds, the count is 2 -> 3
7> After 0.07459495416247286 seconds, the count is 2 -> 3
5> After 0.24680028896240813 seconds, the count is 1 -> 2
8> After 0.18685884099452443 seconds, the count is 3 -> 4
Finishing up
6> After 0.8512297712462166 seconds, the count is 2 -> 4
9> After 0.5959592400151894 seconds, the count is 4 -> 5
Because of the random sleep times between when the variable is stored (oldcnt = counter) and when it is incremented (counter = oldcnt + 1) you get the data race.

Why is my program waiting for a thread that isn't joined?

My program uses threading, but upon calling this certain function of another program (in a thread), the main program waits for the thread to end even though I haven't joined it, just started it.
main.py:
from constant_loops import Constant_loops
import threading
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
z = threading.Thread(target=Constant_loops().add_up(numbers))
z.start()
print("Thread has been finished")
constant_loops.py:
import random
class Constant_loops:
def __init__(self):
global counter
counter = 0
def generate_number(self):
while True:
result = random.randint(1,10)
if result == 1 or result == 10:
print("Desired number obtained")
break
else:
print("Desired number hasn't been obtained yet")
self.add_up(self.numbers)
def add_up(self, numbers):
global counter
self.numbers = numbers
try:
self.numbers[counter] += 1
counter += 1
self.generate_number()
except:
print("Finished one number")
I am aware that there are much simpler ways of doing given task. This is just a simple example of the problem Im having with my main program.

How do you print strings but whenever the user types a specific character it overlaps on whatever is happening and executes the other code in Python3?

Im trying to make something like:
import time
if Action == 1:
while True:
money += 5
time.sleep(5)
and:
Action = input('>')
if Action = 2:
print('You now have $' + str(money) + '!')
so that in the background variable money keeps going up 5 every 5 seconds and whenever the user types in '2' it shows how much the variable money has.
ex.
background:
money = 5
5 secs
money = 10
5 secs
money = 15
3 secs
user: 2
You now have $15!
2 secs
money = 20
Fast code (python 3.6):
import _thread
import time
scope = [dict(action=1, money=0)]
# Define a function for the thread
def money_handler ():
while True:
if scope[0]["action"] == 1:
scope[0]["money"] += 5
if scope[0]["action"] == 2:
scope[0]["money"] += 10
time.sleep(5)
print(scope[0]["money"], scope[0]["action"])
def action_handler():
while True:
time.sleep(5)
scope[0]["action"] = 2 if scope[0]["action"] == 1 else 1
# Create two threads as follows
_thread.start_new_thread(money_handler, ())
_thread.start_new_thread(action_handler, ())
Think about that as 2 separate program flows that interact only with scope variable

How come more threads worsens the perfomance?

The following code gets 2 numbers from the user and calculates how many primes are there between those numbers.
Running the code (between 1 and 1000000) without threads got me 2.8 secs and with 2 threads (my CPU has 2 cores) I got 4.8 secs.
Is it a problem with the PC, the code.
If you could try and run it on your PC and share the results i would thank you for that.
If you see a problem with the code or have any idea why that happens share your toughts.
import math
from threading import Thread
from timeit import timeit
first_num = input()
last_num = input()
primes = []
def is_prime(num):
if num == 2:
return True
if num == 1 or num % 2 == 0:
return False
for i in xrange(3, int(math.sqrt(num)) + 1, 2):
if (num % i == 0):
return False
return True
def find_primes(numbers):
for num in numbers:
if is_prime(num):
primes.append(num)
def targil_a():
find_primes(xrange(first_num, last_num))
print len(primes)
def targil_b():
numbers = range(first_num, last_num)
threads = []
for i in xrange(2):
part_len = int(len(numbers)/2)
t = Thread(target=find_primes, args=(numbers[part_len*i: part_len*(i+1) + 1],))
t.start()
threads.append(t)
for trd in threads:
trd.join()
print len(primes)
print timeit(targil_a, number=1)
primes = []
print timeit(targil_b, number=1)

Resources