2016-04-02 32 views
0

我有一個任務 - 寫入多線程矩陣乘法。每個向量積都必須在新線程中計算(如果我們有n個m和m個k的矩陣,我們必須有n個k個線程)。我還必須顯示結果矩陣元素的計算順序。我寫了代碼並得到了奇怪的結果 - 計算順序幾乎是按順序的。但是我計算了新線程中的每個元素,所以我必須得到結果矩陣元素的隨機計算順序。哪裏不對?這是我的代碼。多線程矩陣乘法C#

using System; 
using System.Threading; 
using System.Collections.Generic; 

namespace MatrixMultiplication 
{ 
class Matrix 
{ 
    public int Row{get; set;} 
    public int Column { get; set;} 
    double[,] arr; 
    Matrix() { } 
    public Matrix(int row,int column) 
    { 
     Row = row; 
     Column = column; 
     arr = new double[row, column]; 
    } 
    public double[] GetColumn(int i) 
    { 
     double[] res=new double[Row]; 
     for (int j = 0; j < Row; j++) 
      res[j] = arr[j, i]; 
     return res; 
    } 
    public double[] GetRow(int i) 
    { 
     double[] res = new double[Column]; 
     for (int j = 0; j < Column; j++) 
      res[j] = arr[i, j]; 
     return res; 
    } 
    public double this[int i,int j] 
    { 
     get { return arr[i, j]; } 
     set { arr[i, j] = value; } 
    } 
    public Matrix RandomValues() 
    { 
     Random rnd=new Random(); 
     for (int i = 0; i < Row; i++) 
      for (int j = 0; j < Column; j++) 
       arr[i, j] =rnd.Next(10); 
     return this; 
    } 

    public void Print() 
    { 
     for(int i=0;i<Row;i++){ 
      for (int j = 0; j < Column; j++) 
       Console.Write(arr[i,j]+" "); 
      Console.WriteLine(); 
     } 
    } 

    public static Matrix operator*(Matrix a, Matrix b) 
    { 
     Matrix result=new Matrix(a.Row,b.Column); 
     List<Thread> threads = new List<Thread>(); 
     for (int i = 0; i <a.Row*b.Column;i++) 
     { 
      int tempi = i; 
      Thread thread = new Thread(()=>VectorMult(tempi, a, b, result)); 
      thread.Start(); 
      threads.Add(thread); 
     } 
     foreach (Thread t in threads) 
      t.Join(); 
     return result; 
    } 

    public static void VectorMult(int tmp, Matrix a, Matrix b,Matrix result){ 
     int i = tmp/b.Column; 
     int j = tmp % b.Column; 
     double[] x = a.GetRow(i); 
     double[] y = b.GetColumn(j); 
     for (int k = 0; k < x.Length; k++) 
      result[i, j] += x[k] * y[k]; 
     Console.WriteLine("Calculate element{0}{1}", i, j); 
    } 
    } 

    class Program 
    { 
    static void Main(string[] args) 
    { 
     int n = int.Parse(Console.ReadLine()); 
     int m = int.Parse(Console.ReadLine()); 
     int k = int.Parse(Console.ReadLine()); 
     Matrix A = new Matrix(n,m).RandomValues(); 
     Matrix B = new Matrix(m,k).RandomValues(); 
     A.Print(); 
     Console.WriteLine(new String('-',20)); 
     B.Print(); 
     Console.WriteLine(new String('-', 20)); 
     Matrix C = A * B; 
     C.Print(); 
    } 
    } 
} 
+0

請檢查你的課程作業筆記。如圖所示的代碼沒有演示如何使用任何最有可能出現的同步原語來獲得及格分數(並且如果真的很在意要得到正確的結果,那麼肯定是必須的)。 –

回答

2

什麼你所描述的是正常的 - 看到this post從今天早些時候演示瞭如何在不同的線程進程沒有預期的序列中始終運行。他們可能會做這麼多或大部分時間,但是你會得到一些意想不到的行爲。

計算是否需要按照特定的順序進行,或者您是否需要能夠看到它們發生的順序?

如果您正在開始新線程,則無法控制序列。 (您已經看到了。)您也無法捕獲它們完成的順序,因爲完成計算並記錄結果(控制檯或任何其他輸出)不是原子操作。

這種情況可能發生:

  1. 計算A完成
  2. 計算乙完成
  3. 計算B被記錄
  4. 計算一個記錄

多線程是不是偉大的,當操作必須以特定的順序發生。

您可以將計算結果插入ConcurrentQueue,因爲它們已完成,並且序列將爲,大多數正確。

+0

我需要查看計算線程的順序。我在程序中輸入幾乎相同的輸入而沒有多線程(我在結果矩陣的元素的屏幕編號上打印)。但我認爲結果矩陣的元素應該按隨機順序來計算。 – Vladyslav

+0

爲了確保我的理解 - 你是否說計算順序可能是隨機的,或者你想使它隨機? –

+0

我想使它隨機。但是我認爲當我計算不同線程的結果矩陣的元素時,計算的順序必須是隨機的。我錯了嗎? – Vladyslav