Compute a matrix of pairwise L2 Euclidean distances among samples from 'data'.
        This computation is to be done in parallel by 'N_processes' distinct processes. 
        Those processes (which are instances of the class 'Similarities_worker') 
        are prevented from simultaneously accessing the HDF5 data structure 
        at 'hdf5_file' through the use of a multiprocessing.Lock object.

def compute_similarities(hdf5_file, data, N_processes):
    """Compute a matrix of pairwise L2 Euclidean distances among samples from 'data'.
        This computation is to be done in parallel by 'N_processes' distinct processes. 
        Those processes (which are instances of the class 'Similarities_worker') 
        are prevented from simultaneously accessing the HDF5 data structure 
        at 'hdf5_file' through the use of a multiprocessing.Lock object.
    """

    slice_queue = multiprocessing.JoinableQueue()
    
    pid_list = []
    for i in range(N_processes):
        worker = Similarities_worker(hdf5_file, '/aff_prop_group/similarities',
                                     data, slice_queue)
        worker.daemon = True
        worker.start()
        pid_list.append(worker.pid)
    
    for rows_slice in chunk_generator(data.shape[0], 2 * N_processes):
        slice_queue.put(rows_slice)
        
    slice_queue.join()    
    slice_queue.close()
    
    terminate_processes(pid_list)
    gc.collect()