try with processing, but data share failed

This commit is contained in:
Richard Feistenauer 2018-12-08 17:45:06 +01:00
parent bad67211ec
commit 530072b1d5
3 changed files with 60 additions and 56 deletions

View File

@ -32,7 +32,7 @@ class WorldGeneratorWindow:
surfaces_to_update = []
for cell in self._cellular_automaton.grid.get_active_cells().values():
if not cell.dirty:
if not cell.is_dirty():
continue
cell_coordinate = cell.coordinate
status = cell.get_status_for_iteration(self._cellular_automaton.get_iteration_index())
@ -45,6 +45,7 @@ class WorldGeneratorWindow:
surface_pos = [x * y for x, y in zip(cell_size, cell_coordinate)]
surface_pos[1] += 20
surfaces_to_update.append(self.screen.fill(cell_color, (surface_pos, cell_size)))
cell.release_dirty()
pygame.display.update(surfaces_to_update)
def main_loop(self):
@ -75,6 +76,7 @@ class WorldGeneratorWindow:
class TestRule(Rule):
def evolve_cell(self, cell, neighbors, iteration_index):
active = False
last_iteration = iteration_index - 1
if cell.get_status_for_iteration(last_iteration) is None:
rand = random.randrange(0, 101, 1)
@ -83,15 +85,18 @@ class TestRule(Rule):
cell.set_status_for_iteration([rand], iteration_index)
cell.set_status_for_iteration([rand], iteration_index + 1)
if rand != 0:
cell.dirty = True
active = True
cell.set_dirty()
elif len(neighbors) == 8:
left_neighbour_status = neighbors[3].get_status_for_iteration(last_iteration)
cell.set_status_for_iteration(left_neighbour_status, iteration_index)
return cell.dirty
active = cell.set_status_for_iteration(left_neighbour_status, iteration_index)
if active:
cell.set_dirty()
return active
if __name__ == "__main__":
rule = TestRule()
ca = CellularAutomaton([500, 500], MooreNeighborhood(EdgeRule.IGNORE_EDGE_CELLS), rule, thread_count=1)
ca = CellularAutomaton([10, 10], MooreNeighborhood(EdgeRule.IGNORE_EDGE_CELLS), rule, thread_count=2)
ca_window = WorldGeneratorWindow([1000, 730], ca)
ca_window.main_loop()

View File

@ -4,19 +4,29 @@ class Cell:
self.coordinate = coordinate
self.neighbours = []
self._status = [None, None]
self.dirty = False
self._dirty = False
def set_neighbours(self, neighbours: list):
self.neighbours = neighbours
def is_dirty(self):
return self._dirty
def set_dirty(self):
self._dirty = True
def release_dirty(self):
self._dirty = False
def set_status_for_iteration(self, new_status, iteration):
""" Will set the new status for Iteration.
:param new_status: The new status to set.
:param iteration: Uses the iteration index, to differ between current and next state.
:return True if status has changed.
"""
self._status[iteration % 2] = new_status
self.dirty = self._status[0] != self._status[1]
return self._status[0] != self._status[1]
def get_status_for_iteration(self, iteration):
""" Will return the status for the iteration.

View File

@ -1,4 +1,4 @@
import threading
import multiprocessing
import time
from cellular_automaton.ca_grid import Grid
@ -9,84 +9,73 @@ from cellular_automaton.ca_neighborhood import Neighborhood
class CellularAutomaton:
def __init__(self, dimension: list, neighborhood: Neighborhood, rule_: Rule=None, thread_count: int=4):
self.grid = Grid(dimension, neighborhood)
self._rule = rule_
self.rule = rule_
self._thread_count = thread_count
self._iteration = 0
self.iteration = 0
self.test_number = 0
def set_rule(self, rule: Rule):
self._rule = rule
self.rule = rule
def set_thread_count(self, thread_count: int):
self._thread_count = thread_count
def get_iteration_index(self):
return self._iteration
return self.iteration
def evolve(self):
""" Evolves all active cells for one time step.
:return: True if all cells are inactive.
"""
if self._all_cells_are_inactive():
return True
else:
self._iteration += 1
self._delegate_evolve_to_threads()
self.iteration += 1
self._start_multi_process_cell_evolution()
return False
def _delegate_evolve_to_threads(self):
cell_lists_for_threats = self.create_cell_lists_for_threads()
def _start_multi_process_cell_evolution(self):
""" Evolves the cells in separate threads """
lists_of_cell_names = self._create_list_of_cell_names_lists_for_all_threads()
self.grid.clear_active_cells()
threads = self._start_treads_to_evolve_grid(cell_lists_for_threats)
self._wait_for_all_threads_to_finish(threads)
jobs = self._start_treads_to_evolve_grid(lists_of_cell_names)
self._wait_for_all_threads_to_finish(jobs)
print(self.test_number)
def _all_cells_are_inactive(self):
return len(self.grid.get_names_of_active_cells()) == 0
def create_cell_lists_for_threads(self):
def _create_list_of_cell_names_lists_for_all_threads(self):
active_cells = self.grid.get_names_of_active_cells()
cell_count_per_thread = int(len(active_cells) / self._thread_count)
return self.divide_active_cells(cell_count_per_thread, active_cells)
return self._divide_list_in_parts_of_size(active_cells, cell_count_per_thread)
@staticmethod
def divide_active_cells(cell_count_per_thread, active_cells):
def _divide_list_in_parts_of_size(active_cells: list, cell_count_per_thread: int):
return [active_cells[i:i + cell_count_per_thread]
for i in range(0, len(active_cells), cell_count_per_thread)]
def _start_treads_to_evolve_grid(self, cell_lists_for_threats):
threads = []
def _start_treads_to_evolve_grid(self, lists_of_cell_names):
jobs = []
for t in range(self._thread_count):
new_thread = _EvolutionThread(self.grid, self._rule, cell_lists_for_threats[t], self._iteration)
threads.append(new_thread)
new_thread.start()
return threads
process = multiprocessing.Process(target=_evolve_cells, args=(self, lists_of_cell_names[t]))
jobs.append(process)
process.start()
return jobs
@staticmethod
def _wait_for_all_threads_to_finish(threads):
for thread in threads:
while not thread.is_finished():
time.sleep(0.01)
thread.join()
def _wait_for_all_threads_to_finish(jobs):
for process in jobs:
process.join()
class _EvolutionThread(threading.Thread):
def __init__(self, grid: Grid, rule: Rule, cell_list: list, iteration: int):
super(_EvolutionThread, self).__init__()
self._grid = grid
self._rule = rule
self._cell_list = cell_list
self._next_state = []
self._finished = False
self._iteration = iteration
def _evolve_cells(cellular_automaton, cell_names: list):
time.sleep(2)
cellular_automaton.test_number += 1
print(cellular_automaton.grid)
for cell_name in cell_names:
cell_info = cellular_automaton.grid.get_cell_and_neighbors(cell_name)
active = cellular_automaton.rule.evolve_cell(cell_info[0], cell_info[1], cellular_automaton.iteration)
def run(self):
for cell in self._cell_list:
cell_info = self._grid.get_cell_and_neighbors(cell)
active = self._rule.evolve_cell(cell_info[0], cell_info[1], self._iteration)
if active:
self._grid.set_cell_and_neighbours_active(cell_info)
self._finished = True
def get_new_cell_states(self):
return self._next_state
def is_finished(self):
return self._finished
if active:
cellular_automaton.grid.set_cell_and_neighbours_active(cell_info)