Why does this multi-threaded program never end? /u/eggtrie Python Education

This is my solution to https://leetcode.com/problems/print-zero-even-odd/

The question is:

You are given an instance of the class ZeroEvenOdd that has three functions: zero, even, and odd. The same instance of ZeroEvenOdd will be passed to three different threads:

Thread A: calls zero() that should only output 0's. Thread B: calls even() that should only output even numbers. Thread C: calls odd() that should only output odd numbers. 

Modify the given class to output the series “010203040506…” where the length of the series must be 2n.

import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 # printNumber(x) outputs "x", where x is an integer. def zero(self, printNumber: 'Callable[[int], None]') -> None: while self._shared_idx < self.n: with self._cond_var: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) printNumber(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self, printNumber: 'Callable[[int], None]') -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 1) def odd(self, printNumber: 'Callable[[int], None]') -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 0) def _print_nonzero_when(self, printNumber, predicate): while self._shared_idx < self.n: with self._cond_var: self._cond_var.wait_for(predicate) printNumber(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() 

However, if I run this code on my computer locally, it does work.

from math import ceil import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 def zero(self) -> None: with self._cond_var: while self._shared_idx < self.n: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) print(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 1) def odd(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 3) def _print_nonzero_when(self, print, predicate): with self._cond_var: while self._shared_idx < self.n: self._cond_var.wait_for(predicate) print(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() zeo = ZeroEvenOdd(2) # with ThreadPoolExecutor(max_workers=3) as executor: # executor.submit(zeo.odd) # executor.submit(zeo.zero) # executor.submit(zeo.even) threads = [ threading.Thread(target=zeo.odd), threading.Thread(target=zeo.even), threading.Thread(target=zeo.zero), ] for t in threads: t.start() for t in threads: t.join() 

submitted by /u/eggtrie
[link] [comments]

​r/learnpython This is my solution to https://leetcode.com/problems/print-zero-even-odd/ The question is: You are given an instance of the class ZeroEvenOdd that has three functions: zero, even, and odd. The same instance of ZeroEvenOdd will be passed to three different threads: Thread A: calls zero() that should only output 0’s. Thread B: calls even() that should only output even numbers. Thread C: calls odd() that should only output odd numbers. Modify the given class to output the series “010203040506…” where the length of the series must be 2n. import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 # printNumber(x) outputs “x”, where x is an integer. def zero(self, printNumber: ‘Callable[[int], None]’) -> None: while self._shared_idx < self.n: with self._cond_var: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) printNumber(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self, printNumber: ‘Callable[[int], None]’) -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 1) def odd(self, printNumber: ‘Callable[[int], None]’) -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 0) def _print_nonzero_when(self, printNumber, predicate): while self._shared_idx < self.n: with self._cond_var: self._cond_var.wait_for(predicate) printNumber(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() However, if I run this code on my computer locally, it does work. from math import ceil import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 def zero(self) -> None: with self._cond_var: while self._shared_idx < self.n: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) print(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 1) def odd(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 3) def _print_nonzero_when(self, print, predicate): with self._cond_var: while self._shared_idx < self.n: self._cond_var.wait_for(predicate) print(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() zeo = ZeroEvenOdd(2) # with ThreadPoolExecutor(max_workers=3) as executor: # executor.submit(zeo.odd) # executor.submit(zeo.zero) # executor.submit(zeo.even) threads = [ threading.Thread(target=zeo.odd), threading.Thread(target=zeo.even), threading.Thread(target=zeo.zero), ] for t in threads: t.start() for t in threads: t.join() submitted by /u/eggtrie [link] [comments] 

This is my solution to https://leetcode.com/problems/print-zero-even-odd/

The question is:

You are given an instance of the class ZeroEvenOdd that has three functions: zero, even, and odd. The same instance of ZeroEvenOdd will be passed to three different threads:

Thread A: calls zero() that should only output 0's. Thread B: calls even() that should only output even numbers. Thread C: calls odd() that should only output odd numbers. 

Modify the given class to output the series “010203040506…” where the length of the series must be 2n.

import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 # printNumber(x) outputs "x", where x is an integer. def zero(self, printNumber: 'Callable[[int], None]') -> None: while self._shared_idx < self.n: with self._cond_var: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) printNumber(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self, printNumber: 'Callable[[int], None]') -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 1) def odd(self, printNumber: 'Callable[[int], None]') -> None: self._print_nonzero_when(printNumber, lambda: self._shared_idx%2 == 0) def _print_nonzero_when(self, printNumber, predicate): while self._shared_idx < self.n: with self._cond_var: self._cond_var.wait_for(predicate) printNumber(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() 

However, if I run this code on my computer locally, it does work.

from math import ceil import threading class ZeroEvenOdd: def __init__(self, n): self.n = n self._cond_var = threading.Condition() self._shared_idx = 0 def zero(self) -> None: with self._cond_var: while self._shared_idx < self.n: # The wait() method releases the lock, and then blocks until another thread # awakens it by calling notify() or notify_all(). self._cond_var.wait_for(lambda: self._shared_idx&1 == 0) print(0) self._shared_idx += 1 self._cond_var.notify_all() def even(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 1) def odd(self) -> None: self._print_nonzero_when(print, lambda: self._shared_idx%4 == 3) def _print_nonzero_when(self, print, predicate): with self._cond_var: while self._shared_idx < self.n: self._cond_var.wait_for(predicate) print(int(ceil(self._shared_idx/2))) self._shared_idx += 1 self._cond_var.notify_all() zeo = ZeroEvenOdd(2) # with ThreadPoolExecutor(max_workers=3) as executor: # executor.submit(zeo.odd) # executor.submit(zeo.zero) # executor.submit(zeo.even) threads = [ threading.Thread(target=zeo.odd), threading.Thread(target=zeo.even), threading.Thread(target=zeo.zero), ] for t in threads: t.start() for t in threads: t.join() 

submitted by /u/eggtrie
[link] [comments] 

Leave a Reply

Your email address will not be published. Required fields are marked *