Реализация многопоточности в цикле for в c # без Parallel.For () - PullRequest
0 голосов
/ 24 ноября 2018

Я относительно новичок в многопоточности. Я написал цикл for для печати значений от 0 до целого числа, указанного пользователем. Теперь я хочу распараллелить его таким образом, чтобы каждый поток печатал 5 чисел. Он работаеткогда я использую Parallel.For (). Но я не могу сделать это вручную. Вот код.

using System;
using System.Threading;

namespace ConsoleApp1
{
class Program
{
    static int no = 0;
    static void Main(string[] args)
    {
        Console.WriteLine("Enter a number");
        no = int.Parse(Console.ReadLine());

        //Parallel.For(0, no, i =>
        //Console.WriteLine(i)
        //);
        //Console.ReadLine();
        int start = 0, end = 5, i = 0;
        int not = no / 5;

        if (no <= 5)
        {
            func(start, no);
        }

        else
        {
            int index = i;
            Thread[] t = new Thread[not + 1];

            while (index < not + 1)
            {
                if (end - start >= 5 && end <= no)
                    t[index] = new Thread(() => func(start, end));

                else
                    t[index] = new Thread(() => func(start, no));

                start = end;
                end = end + 5;

                i++;
                t[index].Start();

            }
          Console.ReadLine();
        }
    }

    static public void func(int start, int end)
    {

        for (int i = start; i < end; i++)
        {
            Console.Write(i+",");
        }
    }
}
}

Предположим, что пользовательское значение ввода равно 21. Затем он выдает следующий вывод

15,16,17,15,16,17,18,19,18,19,25,26,27,28,29,25,26,27,28,29

Однако после использования thread.join () сразу после t [index] .start () получается следующий вывод.

5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24

Кажется, я не понимаю, что происходити я не могу отладить этот код, так как одновременно запущено много потоков.

Заранее спасибо

1 Ответ

0 голосов
/ 24 ноября 2018

Обратите внимание, что лямбда-выражение типа () => func(start, end) связано с переменными начала и конца и будет при исполнении использовать значение, которое переменные имели в данный момент, а не значения, которые они имели при создании потока.

Вы можете избежать этого, сначала назначив текущие значения переменным, определенным в цикле, и используя их в своих лямбдах, например,

if (end - start >= 5 && end <= no)
{
    var localStart = start;
    var localEnd = end;
    t[index] = new Thread(() => func(localStart, localEnd));
}
else
{
    var localStart = start;
    var localEnd = no;
    t[index] = new Thread(() => func(localStart, localEnd));
}
...