2016-04-02 84 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