Mnożenie macierzy - wątki i semafor

Odpowiedz Nowy wątek
Pytający_Desperat
2016-10-22 18:03
Pytający_Desperat
0

Cześć, mam do zrobienia program, który mnoży macierze kwadratowe i musi wykorzystywać semafory do synchronizacji wątków. Problem w tym, że dopiero zaczynam tę tematykę i nie za bardzo ogarniam te semafory, więc nawet nie wiem z jakimi wartościami najlepiej go zainicjować. Tak czy siak dodałem już te wątki i semafor, to macierz wynikowa albo jest wypełniona zerami i program się zamyśla albo są wyliczone tylko niektóre z wierszy. Co mam poprawić?

class Program
{
    private static Semaphore semaphore = new Semaphore(0, 1);
    static void Main(string[] args)
    {
        int size;
        int[,] a = null, b = null, c = null;
        bool isNumeric;
        do
        {
            Console.Write("Podaj wielkość macierzy: ");
            isNumeric = int.TryParse(Console.ReadLine(), out size);
        }
        while (!isNumeric || size < 2);
        Console.WriteLine();
        SquareMatrix.Init(size, ref a);
        SquareMatrix.Init(size, ref b);
        SquareMatrix.Init(size, ref c);
        SquareMatrix.Fill(a);
        SquareMatrix.Fill(b);
        Console.WriteLine("Macierz 1:\n");
        SquareMatrix.Display(a);
        Console.WriteLine("Macierz 2:\n");
        SquareMatrix.Display(b);
        Console.WriteLine();
        DateTime start = DateTime.Now;
        for (int i = 0; i < size; i++)
        {
            Thread thread = new Thread(() => Multiply(i, size, a, b, c));
            thread.Start();
        }
        DateTime stop = DateTime.Now;
        Console.WriteLine("Wynik:\n");
        SquareMatrix.Display(c);
        Console.WriteLine("Czas: " + (stop - start).TotalMilliseconds + " ms");
        Console.ReadLine();
    }
    public static void Multiply(int i, int size, int[,] a, int[,] b, int[,] c)
    {
        semaphore.WaitOne();
        for (int j = 0; j < size; j++)
        {
            c[i, j] = 0;
            for (int k = 0; k < size; k++)
            {
                c[i, j] += a[i, k] * b[k, j];
            }
        }
        semaphore.Release();
    }
}

SquareMatrix to klasa statyczna z metodami do inicjowania macierzy, wypełniania ich liczbami pseudolosowymi oraz wyświetlania, nie ma potrzeby wrzucać jej kodu. Z góry dzięki.

edytowany 1x, ostatnio: DibbyDum, 2016-12-13 18:26

Pozostało 580 znaków

Pytający_Desperat
2016-10-22 18:18
Pytający_Desperat
0

Pomogło dodanie
thread.Join();
pod
thread.Start();
lecz nadal nie jestem pewien, czy to faktycznie spełnia warunki równoległości. Proszę o pomoc.

Pozostało 580 znaków

2016-10-25 10:45

Rejestracja: 17 lat temu

Ostatnio: 3 dni temu

0

Ten program jest dziwny. Począwszy od:

while (!isNumeric || size < 2);

Co to miałoby w ogóle robić?

Poza tym stosujesz wątki i fajnie. Ale i tak w Twoim przypadku czas policzenia tego będzie dłuższy niż bez wątków. A to dlatego, że nie ogarniasz semaforów, czy też innych takich konstrukcji.

Po pierwsze, jeśli w Multiply będzie jakikolwiek błąd, to wątki się zakleszczą, a program zawiesi na amen. Dlatego, że jeśli będzie błąd, to semaphore.Release() nigdy się nie wywoła, w związku z tym jeden wątek nigdy się nie rozpocznie.

Po drugie, Twój kod działa w następujący sposób.
Niech stanie się wątek.
Niech ten wątek robi swoją pracę.
Niech stanie się drugi wątek.
Niech drugi wątek robi swoją pracę.
Ojoj, drugi wątek nie może robić swojej pracy, bo ma opuszczony semaforek. Drugi wątek musi poczekać aż pierwszy zakończy swoją pracę i dopiero wtedy będzie mógł rozpocząć swoją.

Semafory i inne tego typu blokady są potrzebne wtedy, gdy wątki pracują na wspólnych danych. Tutaj nie widzę żadnych wspólnych danych, a więc semafory są bez sensu. Zresztą ten temat (synchronizacja wątków) nie jest prosty i oczywisty. Musisz sporo poczytać na ten temat i popełnić kilka błędów, żebyś wiedział jak to ugryźć poprawnie.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0