Elementos no repetitivos de una array determinada utilizando un programa de subprocesos múltiples

Dada una array arr[] de tamaño N y un entero T que representa el recuento de subprocesos , la tarea es encontrar todos los elementos de la array que no se repiten utilizando subprocesos múltiples .

Ejemplos:

Entrada: arr[] = { 1, 0, 5, 5, 2}, T = 3 
Salida: 0 1 2 
Explicación: 
La frecuencia de 0 en el arreglo arr[] es 1. 
La frecuencia de 1 en el arreglo arr[ ] es 1. 
La frecuencia de 2 en el arreglo arr[] es 1. 
Por lo tanto, la salida requerida es 0 1 2

Entrada: arr[] = { 1, 1, 5, 5, 2, 4 }, T = 3 
Salida: 2 4 
Explicación: 
La frecuencia de 2 en el arreglo arr[] es 1. 
La frecuencia de 4 en el arreglo arr [] es 1. 
Por lo tanto, la salida requerida es 2 4

Enfoque: la idea es utilizar la biblioteca pthread disponible en C++ para crear múltiples subprocesos para el flujo de procesos simultáneos y realizar múltiples operaciones (pthread create, pthread join, lock, etc.) en un programa multiproceso. Siga los pasos a continuación para resolver el problema:

  • Divida la array en T subarreglos, de modo que cada subarreglo de tamaño N / T se ejecute en un solo subproceso.
  • Inicialice un mapa , digamos mp , para almacenar las frecuencias de cada elemento del arreglo .
  • Cree un pthread_mutex_lock , digamos lock1 , para garantizar que todos los subprocesos no tropiecen entre sí y dañen el contenedor del mapa.
  • Defina una función func() para ejecutar el cuerpo de un hilo. Esta función a menudo se denomina núcleo del subproceso y se proporciona durante la creación del subproceso.
    • Bloquee el hilo actual usando pthread_mutex_lock() para que no se superponga con otros hilos
    • Recorra el rango dado como un argumento para la función func() en la array arr[] e incremente la frecuencia del elemento de la array que se encuentra.
    • Libera el hilo actual usando la función pthread_mutex_unlock() .
  • Inicialice una array, digamos thread[] , de tipo pthread_t para almacenar los hilos.
  • Itere sobre el rango [0, T] y cree un hilo llamando a la función pthread_create() y guárdelo en el hilo [i]
  • Mientras cada subproceso realiza sus tareas individuales, la función main() deberá esperar hasta que cada uno de los subprocesos finalice su trabajo. 
    • Use la función pthread_join() para esperar hasta que cada subproceso termine de ejecutar la función func()
    • Iterar sobre el rango [0, T] y llamar a la función pthread_create() para cada hilo [i]
  • Finalmente, recorra el mapa mp e imprima el elemento que aparece solo una vez.

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
#include <pthread.h>
using namespace std;
 
// Structure of subarray
// of the array
struct range_info {
 
    // Stores start index
    // of the subarray
    int start;
 
    // Stores end index
    // of the subarray
    int end;
 
    // Stores pointer to the
    // first array element
    int* a;
};
 
 
// Declaring map, and mutex for
// thread exclusion(lock)
map<int, int> mp;
pthread_mutex_t lock1;
 
 
// Function performed by every thread to
// count the frequency of array elements
// in current subarray
void* func(void* arg)
{
    // Taking a lock so that threads
    // do not overlap each other
    pthread_mutex_lock(&lock1);
     
     
    // Initialize range_info
    // for each thread
    struct range_info* rptr
    = (struct range_info*)arg;
 
 
    // Thread is going through the array
    // to check and update the map
    for (int i = rptr->start;
            i <= rptr->end; i++) {
                     
         
        // Stores iterator to the map        
        map<int, int>::iterator it;
         
         
        // Update it
        it = mp.find(rptr->a[i]);
         
         
        // If rptr->a[i] not found
        // in map mp
        if (it == mp.end()) {
             
             
            // Insert rptr->a[i] with
            // frequency 1
            mp.insert({ rptr->a[i], 1 });
        }
        else {
             
             
            // Update frequency of
            // current element
            it->second++;
        }
    }
     
 
    // Thread releases the lock
    pthread_mutex_unlock(&lock1);
    return NULL;
}
 
 
// Function to find the unique
// numbers in the array
void numbers_occuring_once(int arr[],
                        int N, int T)
{
    // Stores all threads
    pthread_t threads[T];
 
    // Stores start index of
    // first thread
    int spos = 0;
 
    // Stores last index
    // of the first thread
    int epos = spos + (N / T) - 1;
 
    // Traverse each thread
    for (int i = 0; i < T; i++) {
 
        // Initialize range_info for
        // current thread
        struct range_info* rptr
            = (struct range_info*)malloc(
                sizeof(struct range_info));
 
        // Update start index of
        // current subarray    
        rptr->start = spos;
 
        // Stores end index of
        // current subarray
        rptr->end = epos;
 
        // Update pointer to the first
        // element of the array
        rptr->a = arr;
         
         
        // creating each thread with
        // appropriate parameters
        int a
        = pthread_create(&threads[i], NULL,
                        func, (void*)(rptr));
                         
                         
        // updating the parameters
        // for the next thread
        spos = epos + 1;
        epos = spos + (N / T) - 1;
        if (i == T - 2) {
            epos = N - 1;
        }
    }
 
    // Waiting for threads to finish
    for (int i = 0; i < T; i++) {
        int rc
        = pthread_join(threads[i], NULL);
    }
 
    // Traverse the map
    for (auto it: mp) {
                 
                 
                                     
    // If frequency of current
    // element is 1                            
        if (it.second == 1) {
 
            // Print the element
            cout << it.first << " ";
        }
    }
}
 
 
// Drivers Code
int main()
{
    // initializing the mutex lock
    pthread_mutex_init(&lock1, NULL);
    int T = 3;
    int arr[] = { 1, 0, 5, 5, 2, 6 };
    int N = sizeof(arr) / sizeof(arr[0]);
    numbers_occuring_once(arr, N, T);
}
Producción: 

 

 

Complejidad de tiempo: O(N * log(N))
Espacio auxiliar: O(N)

Nota: Se recomienda ejecutar el programa en un sistema basado en Linux usando el siguiente comando:

g++ -pthread nombre_programa.cpp

Publicación traducida automáticamente

Artículo escrito por sanj27272 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *