def thread_func(start, end): try: out_edges = mlsl.edges(vertices, min_length, max_length, start, end) lock.acquire() try: output.extend(out_edges) finally: lock.release() finally: done.release()
def edges(vertices, min_length, max_length, start_vertex=0, end_vertex=None, threads=2): if end_vertex is None: end_vertex = len(vertices) if threads < 1: raise Error('the argument threads must be positive') if threads < 2: return mlsl.edges(vertices, min_length, max_length, start_vertex, end_vertex) output = [] lock = threading.RLock() done = threading.Semaphore(0) def thread_func(start, end): try: out_edges = mlsl.edges(vertices, min_length, max_length, start, end) lock.acquire() try: output.extend(out_edges) finally: lock.release() finally: done.release() starts = [] ends = [] begin_edges = start_vertex - 1 end_edges = end_vertex - 2 total_edges = (end_vertex-start_vertex) * (end_vertex+start_vertex-3) / 2 edges_per_thread = total_edges / threads + 1 cur_start = start_vertex for j in range(threads): if cur_start >= end_vertex: break bucket = 0 for end in range(cur_start,end_vertex+1): if bucket >= edges_per_thread: starts.append(cur_start) ends.append(end) cur_start = end break bucket += (end-1) starts.append(cur_start) ends.append(end_vertex) break if ends[-1] != end_vertex: raise Error("Unable to allocate jobs") for j in range(len(starts)): thread.start_new_thread(thread_func, (starts[j],ends[j])) for j in range(len(starts)): done.acquire() return output