Многопоточный поиск в матрице, индекс строки не отображается должным образом - PullRequest
0 голосов
/ 25 октября 2019

Это мой первый вопрос по StackOverflow. Я пытаюсь выполнить упражнение на мьютексах в C, которое просит меня найти элемент в матрице N x N. Каждый поток должен проверять каждую строку для элемента. Когда поток находит элемент, он должен сообщить другим, чтобы они могли выйти без продолжения поиска. Я написал решение, используя флаг, чтобы проверить, был ли найден элемент, но не могу понять, почему индекс строки не отображается должным образом. Я думал, что адрес памяти в матрице является смежным, поэтому я подумал, что использование операнда% может мне помочьЯ не уверен, что функция потока написана правильно. Не могли бы вы помочь мне понять, почему индекс строки не отображается правильно? А есть ли другие элегантные решения?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define MAXNTHREADS 1000000
#define MIN(a,b) (a < b ? a : b)

void * search (void *);
int nthreads;
char tosearch;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int flag;

int main (int argc, char **argv)
{
    pthread_t * threads;
    char * matrix;

    if (argc != 3)
    {
        fprintf (stderr, "usage: matrix <char> <#threads>\n");
        exit (-1);
    }

    nthreads = MIN (atoi(argv[2]), MAXNTHREADS);
    tosearch = argv[1][0];

    matrix = malloc (nthreads * nthreads);
    threads = malloc (sizeof (pthread_t) * nthreads);

    printf ("Insert %d elements\n", nthreads * nthreads);

    for (int i = 0; i < nthreads; i ++)
    {
        for (int j = 0; j < nthreads; j ++)
        {
            scanf ("%c", matrix + i * nthreads + j);
            getchar();  
        }
    }

    printf ("MATRIX:\n");
    for (int i = 0; i < nthreads; i ++)
    {
        for (int j = 0; j < nthreads; j ++)
        {
            printf ("%c\t", *(matrix + i * nthreads + j));  
        }

        printf ("\n");
    }



    for (int i = 0; i < nthreads; i ++)
    {
        pthread_create (threads + i, NULL, search, matrix + i * nthreads);
    }

    for (int i = 0; i < nthreads; i ++)
    {
        pthread_join (* (threads + i), NULL);
    }

    free (matrix);
    free (threads);

    exit (0);
}

void * search (void *arg)
{
    printf ("Process %ld started\n", pthread_self());

    for (int i = 0; i < nthreads; i ++)
    {

        pthread_mutex_lock (&mutex);
        if (flag == 0)
        {
            if (*((char *)arg + i) == tosearch)
            {
                printf ("Element found by thread %ld in position %ld %d\n", pthread_self(),  (((unsigned long)arg + nthreads) % nthreads), i);
                flag  = 1;
                pthread_mutex_unlock (&mutex);
                return NULL;
            }

            pthread_mutex_unlock (&mutex);
        }
        else
        {
            pthread_mutex_unlock (&mutex);
            printf ("Process %ld exits\n", pthread_self());
            pthread_exit (NULL);
        }
    }

    printf ("Process %ld, found nothing\n", pthread_self());
    pthread_exit (NULL);
}

1 Ответ

0 голосов
/ 25 октября 2019

Я решил проблему с индексом, сохранив указатель на матрицу как глобальную переменную. Затем я вычитаю начальный адрес матрицы из адреса элемента и делю результат на nthreads. Таким образом, у меня есть правильный индекс строки элемента. Во всяком случае, я не уверен, что это элегантное решение этой проблемы.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define MAXNTHREADS 1000000
#define MIN(a,b) (a < b ? a : b)

void * search (void *);
int nthreads;
char tosearch;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int flag;
char *matrix;

Затем в функции поиска:

void * search (void *arg)
{
    printf ("Process %ld started\n", pthread_self());

    for (int i = 0; i < nthreads; i ++)
    {

        pthread_mutex_lock (&mutex);
        if (flag == 0)
        {
            if (*((char *)arg + i) == tosearch)
            {
                printf ("Element found by thread %ld in position %ld %d\n", pthread_self(), (((unsigned long)arg + i) - (unsigned long)matrix) / nthreads, i);
                flag  = 1;
                pthread_mutex_unlock (&mutex);
                return NULL;
            }

            pthread_mutex_unlock (&mutex);
        }
        else
        {
            pthread_mutex_unlock (&mutex);
            printf ("Process %ld exits\n", pthread_self());
            pthread_exit (NULL);
        }
    }

    printf ("Process %ld, found nothing\n", pthread_self());
    pthread_exit (NULL);
}
...