c# - C#中五个线程之间的时间分片

标签 c# multithreading file-io job-scheduling round-robin

下面是对程序应该做什么的描述。该程序应该创建一个文件和五个线程来写入该文件...

第一个线程应该将 1 到 5 写入该文件。 第二个线程应该写入 1 到 10。 第三个线程应该写入 1 到 15。 第四个线程应该写入 1 到 20。 第五个线程应该写入 1 到 25。

此外,应该实现一种算法,使每个线程打印 2 个数字并停止。下一个线程应该打印两个数字并停止。依此类推,直到所有线程都打印完它们的数字。 这是我到目前为止开发的代码...

using System;
using System.IO;
using System.Threading;
using System.Collections;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public static class OSAssignment
    {
        // First Thread Tasks...
        static void FirstThreadTasks(StreamWriter WritingBuffer)
        {
            for (int i = 1; i <= 5; i++)
            {
                if (i % 2 == 0)
                {
                    Console.WriteLine("[Thread1] " + i);
                    Thread.Sleep(i);
                }

                else
                {
                    Console.WriteLine("[Thread1] " + i);
                }
            }
        }

        // Second Thread Tasks...
        static void SecondThreadTasks(StreamWriter WritingBuffer)
        {
            for (int i = 1; i <= 10; i++)
            {
                if (i % 2 == 0)
                {
                    if (i == 10)
                        Console.WriteLine("[Thread2] " + i);

                    else
                    {
                        Console.WriteLine("[Thread2] " + i);
                        Thread.Sleep(i);
                    }
                }

                else
                {
                    Console.WriteLine("[Thread2] " + i);
                }
            }
        }

        // Third Thread Tasks..
        static void ThirdThreadTasks(StreamWriter WritingBuffer)
        {
            for (int i = 1; i <= 15; i++)
            {
                if (i % 2 == 0)
                {
                    Console.WriteLine("[Thread3] " + i);
                    Thread.Sleep(i);
                }

                else
                {
                    Console.WriteLine("[Thread3] " + i);
                }
            }
        }

        // Fourth Thread Tasks...
        static void FourthThreadTasks(StreamWriter WritingBuffer)
        {
            for (int i = 1; i <= 20; i++)
            {
                if (i % 2 == 0)
                {
                    if (i == 20)
                        Console.WriteLine("[Thread4] " + i);
                    else
                    {
                        Console.WriteLine("[Thread4] " + i);
                        Thread.Sleep(i);
                    }
                }

                else
                {
                    Console.WriteLine("[Thread4] " + i);
                }

            }
        }

        // Fifth Thread Tasks...
        static void FifthThreadTasks(StreamWriter WritingBuffer)
        {
            for (int i = 1; i <= 25; i++)
            {
                if (i % 2 == 0)
                {
                    Console.WriteLine("[Thread5] " + i);
                    Thread.Sleep(i);
                }

                else
                {
                    Console.WriteLine("[Thread5] " + i);
                }

            }
        }

        // Main Function...
        static void Main(string[] args)
        {
            FileStream File = new FileStream("output.txt", FileMode.Create, FileAccess.Write, FileShare.Write);
            StreamWriter Writer = new StreamWriter(File);
            Thread T1 = new Thread(() => FirstThreadTasks(Writer));
            Thread T2 = new Thread(() => SecondThreadTasks(Writer));
            Thread T3 = new Thread(() => ThirdThreadTasks(Writer));
            Thread T4 = new Thread(() => FourthThreadTasks(Writer));
            Thread T5 = new Thread(() => FifthThreadTasks(Writer));
            Console.WriteLine("Initiating Jobs...");
            T1.Start();
            T2.Start();
            T3.Start();
            T4.Start();
            T5.Start();
            Writer.Flush();
            Writer.Close();
            File.Close();
        }
    }
}

这是我面临的问题...

  1. 即使制作 FileShare.Write,我也不知道如何让 5 个线程同时写入同一个文件。所以我只是决定暂时写入控制台并开发算法并先在控制台中查看它的行为。

  2. 每次我运行程序时,输出都与之前略有不同。一个线程在特定迭代中只打印其中一个数字并在另一个线程完成其当前迭​​代后继续输出第二个数字的情况总是会发生。

  3. 我有一个问题可能有点跑题了。如果我从 main 方法中删除 Console.WriteLine("Initiating Jobs...");,算法将不会像我在第 2 点中提到的那样运行。我真的不明白为什么.

最佳答案

  1. 您的主要功能是在线程开始写入文件之前完成并关闭文件,因此您可以使用 Thread.Join 来等待线程退出。此外,我建议对 IDisposable 对象使用 using 语句。

  2. 当您想要在线程之间共享有限的资源时,您将需要一种锁定机制。线程调度是不确定的。您已经启动了 5 个线程,此时无法保证哪个会先运行。 lock 将强制线程等待资源空闲。顺序仍未确定,因此 T3 可能会在 T2 之前运行,除非您添加额外的逻辑/锁定来强制执行顺序。

  3. 我没有发现行为有太大差异,但自由运行的线程会产生一些很难发现的错误,尤其是与计时问题相关的错误。

作为额外说明,我会避免使用 Sleep 作为同步线程的方式。

为了有效地让一个线程一次写入,您需要阻塞所有其他线程,有一些方法可以做到这一点,例如 lockMutexMonitorAutoResetEvent 等。对于这种情况,我会使用 AutoResetEvent。您随后面临的问题是每个线程都需要知道它正在等待哪个线程,以便它可以等待正确的事件。

关于c# - C#中五个线程之间的时间分片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26922905/

相关文章:

c# - SQLCommand ExecuteNonQuery 最大 CommandText 长度?

python - 从线程停止 WxPython 应用程序的主循环需要窗口焦点

linux - Linux 中的 getrusage(RUSAGE_THREAD, ...) 和 clock_gettime(CLOCK_THREAD_CPUTIME_ID, ...) 有什么区别?

java - 改进类的多个实例访问同一类中多个同步函数的工作流程

python - rw+ 和 r+ 有什么区别

c - 用于对名称列表进行排序的 Perl 脚本,从 C 脚本传递的文件名,然后将排序后的列表传回

c# - .NET 内存不足异常

c# - 打开没有vsto插件的excel

c# - asp.net中的类库和静态变量

c# - (读取)文件 I/O 抖动