我的互斥体无法正常工作。我在读取数据时遇到问题

时间:2019-08-28 12:55:55

标签: c# multithreading mutex

我在C#中有一个多线程程序。它读取文件列表。读取相关文件后,线程完成其任务并完成。我有一个线程数组,因为我有内存限制。当前线程终止后,我开始在同一线程中读取文件。我的问题是:尽管我使用互斥锁,但输入了线程并增加了文件计数器,并且读取了10个以上的文件(例如,在代码中)。我不知道为什么...

我尝试使用锁或监视器而不是互斥锁,但这不能解决问题。

我在代码后添加了打印输出。

    readonly Mutex m1 = new Mutex();
    int thIdx = 0, thAll = 0;
    List<string> file_l = new List<string>();
    Thread[,] arr = new Thread[4, 2];


    static void Main()
    {
        for (int i = 0; i < cDev; i++)
        {
                for (int j = 0; j < cTrd; j++)
                {
                    int xi = i, xj = j;
                    StartThread(xi, xj);
                }
            }
    }               


    private void StartThread(int i, int j)
    {
        arr[i, j] = new Thread(() => Busy(i, j));
        arr[i, j].Start();

        Console.WriteLine($"started T[{i},{j}]    StartTime = {DateTime.Now}.{DateTime.Now.Ticks}");
        thIdx++;
        thAll++;
    }

    private void CriticalSection(Mutex m, DelegateType fun)
    {            
        m.WaitOne();
        try
        {
            /* critical code */
            fun();
        }
        finally
        {
            m.ReleaseMutex();
        }
    }


      bool doneAll = false;

    private void Busy(int i, int j)
    {
        // get file index for executind
        int k = 0;
        int k1 = 0;

        // ** here is mutex and problem **
        CriticalSection(m1, () =>
        {
            k = db.GetFileID(); // do id++ in db
            k1 = k + 1;
            if (k1 == 10) //file_l.Count
            {
                doneAll = true;
            }
        });


        // Busy
        Console.WriteLine($"busy T[{i},{j}]          {k}  -  {file_l[k]}{i}{j}");
        DateTime startTime = DateTime.Now;
        string exec = "";

        Thread.Sleep(3000);

        Console.WriteLine($"finished T[{i},{j}]    * {k}  -   ({DateTime.Now - startTime})   -  command = {exec}");
        thIdx--;

        if (doneAll && thIdx == 0)
        {
            Console.WriteLine($"finished all  -   ({DateTime.Now - startTimeAll})   -   files = {thAll}");
            Console.WriteLine("end");
        }


        if (doneAll)
        {
            arr[i, j].Abort(); // release thread
        }
        else if (k1 < 10) 
        {
                StartThread(i, j);               
        }
    }

输出:

started T[0,0]    StartTime = 28/08/2019 13:02:19.637025941396299385

started T[0,1]    StartTime = 28/08/2019 13:02:19.637025941396339280

busy T[0,0]          0  -  3562634_04018610_2_CROP.MPG00

busy T[0,1]          1  -  6236814_04073221_1_CROP.MPG01

started T[3,0]    StartTime = 28/08/2019 13:02:19.637025941396359231

busy T[3,0]          2  -  5886591_04081109_2_CROP.MPG30

started T[3,1]    StartTime = 28/08/2019 13:02:19.637025941396379179

busy T[3,1]          3  -  3747967_04040496_3_CROP.MPG31

finished T[0,0]    * 0  -   (00:00:03.0278023)   -  command = sleep 3

finished T[3,0]    * 2  -   (00:00:03.0258075)   -  command = sleep 3

finished T[3,1]    * 3  -   (00:00:03.0238131)   -  command = sleep 3

started T[0,0]    StartTime = 28/08/2019 13:02:22.637025941426637254

finished T[0,1]    * 1  -   (00:00:03.0278023)   -  command = sleep 3

started T[3,0]    StartTime = 28/08/2019 13:02:22.637025941426647250

busy T[0,0]          4  -  3562909_04015124_3_CROP.MPG00

started T[3,1]    StartTime = 28/08/2019 13:02:22.637025941426687119

busy T[3,1]          5  -  6347131_04081352_1_CROP.MPG31

busy T[3,0]          6  -  4005567_04043606_4_CROP.MPG30

started T[0,1]    StartTime = 28/08/2019 13:02:22.637025941426766913

busy T[0,1]          7  -  4005566_04043601_2_CROP.MPG01

finished T[0,0]    * 4  -   (00:00:03.0055051)   -  command = sleep 3

started T[0,0]    StartTime = 28/08/2019 13:02:25.637025941456762049

busy T[0,0]          8  -  3562434_04040432_2_CROP.MPG00

finished T[3,1]    * 5  -   (00:00:03.0324275)   -  command = sleep 3

finished T[3,0]    * 6  -   (00:00:03.0284380)   -  command = sleep 3

started T[3,1]    StartTime = 28/08/2019 13:02:25.637025941457051293

finished T[0,1]    * 7  -   (00:00:03.0264398)   -  command = sleep 3

started T[3,0]    StartTime = 28/08/2019 13:02:25.637025941457081178

busy T[3,0]          9  -  3740413_04012542_2_CROP.MPG30

started T[0,1]    StartTime = 28/08/2019 13:02:25.637025941457160961

busy T[0,1]          10  -  3562404_04015032_2_CROP.MPG01

busy T[3,1]          11  -  5914063_04081061_1_CROP.MPG31

finished T[0,0]    * 8  -   (00:00:03.0058500)   -  command = sleep 3

finished T[3,0]    * 9  -   (00:00:03.0108370)   -  command = sleep 3

finished T[0,1]    * 10  -   (00:00:03.0310286)   -  command = sleep 3

finished T[3,1]    * 11  -   (00:00:03.0529614)   -  command = sleep 3

finished all  -   (00:00:09.1713083)   -   files = 12

end

我希望在这种情况下可以readind 10个文件,但在12个文件后它会停止

1 个答案:

答案 0 :(得分:0)

我认为您的问题出在db.GetFileID()函数中。您期望db中的值已更新,但实际上并没有。尝试使用全局变量(而不是此函数的结果)来控制线程数。