2016-03-28 60 views
0

我在线程中运行两个函数。一个有循环,第二个等待输入,所以当输入发生时,它应该暂停第一个循环线程并要求在同一个第二个线程中恢复或终止线程... ???暂停和恢复从另一个线程在C中的线程#

下面你可以看到,我想实现这个逻辑我的代码...

class Program 
    { 
     public static int flag = 0; 
     public static int process; 
     public static int quantum; 
     public static int[] execTime = new int[10]; 
     public static string[] P0 = new string[100]; 
     public static string[] P1 = new string[100]; 
     public static string[] P2 = new string[100]; 
     public static string[] P3 = new string[100]; 
     public static string[] P4 = new string[100]; 
     public static string[] P5 = new string[100]; 
     public static string[] P6 = new string[100]; 
     public static string[] P7 = new string[100]; 
     public static string[] P8 = new string[100]; 
     public static string[] P9 = new string[100]; 
     public static void Main(string[] args) 
     { 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This   
      //************************// 
      //*** Filling Process ***// 
      //************************// 
      for (int i = 0; i < P0.Length; i++) 
      { 
       P0[i] = "P0." + i;     
      } 
      for (int i = 0; i < P1.Length; i++) 
      { 
       P1[i] = "P1." + i; 
      } 
      for (int i = 0; i < P2.Length; i++) 
      { 
       P2[i] = "P2." + i; 
      } 
      for (int i = 0; i < P3.Length; i++) 
      { 
       P3[i] = "P3." + i; 
      } 
      for (int i = 0; i < P4.Length; i++) 
      { 
       P4[i] = "P4." + i; 
      } 
      for (int i = 0; i < P5.Length; i++) 
      { 
       P5[i] = "P5." + i; 
      } 
      for (int i = 0; i < P6.Length; i++) 
      { 
       P6[i] = "P6." + i; 
      } 
      for (int i = 0; i < P7.Length; i++) 
      { 
       P7[i] = "P7." + i; 
      } 
      for (int i = 0; i < P8.Length; i++) 
      { 
       P8[i] = "P8." + i; 
      } 
      for (int i = 0; i < P9.Length; i++) 
      { 
       P9[i] = "P9." + i; 
      } 

      //************************// 
      //*** Creating Process ***// 
      //************************// 
      do 
      { 
       Console.Write("How Many Process You Want To Create? (0-10) "); 
       process = Convert.ToInt16(Console.ReadLine()); 
       if (process > 10) 
       { 
        Console.ForegroundColor = ConsoleColor.Red; // Red Color Text Below This 
        Console.WriteLine("Error => Your Process Should Be Less Then 10."); 
        Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 
       } 
      } while (process > 10); 
      Console.ForegroundColor = ConsoleColor.Green; // Green Color Text Below This 
      Console.WriteLine("Success =>" + process + " Process Have Been Generated."); 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 

      //***************************************// 
      //*** Creating Process Executing TIme ***// 
      //***************************************// 
      for (int i = 0; i < process; i++) 
      {     
       do 
       { 
        Console.Write("What\'s The Executing Time Your Process # " + i + "? (0-100) "); 
        execTime[i] = Convert.ToInt16(Console.ReadLine()); 
        if (execTime[i] > 100) 
        { 
         Console.ForegroundColor = ConsoleColor.Red; // Red Color Text Below This 
         Console.WriteLine("Error => Your Executing Time Should Be Less Then 100."); 
         Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 
        } 
       } while (execTime[i] > 100); 
      } 
      Console.ForegroundColor = ConsoleColor.Green; // Green Color Text Below This 
      Console.WriteLine("Success =>" + process + " Executing Time Have Been Generated."); 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 

      //**************************************// 
      //*** Resizing Process Array's Steps ***// 
      //**************************************// 
      Array.Resize(ref P0, execTime[0]); 
      Array.Resize(ref P1, execTime[1]); 
      Array.Resize(ref P2, execTime[2]); 
      Array.Resize(ref P3, execTime[3]); 
      Array.Resize(ref P4, execTime[4]); 
      Array.Resize(ref P5, execTime[5]); 
      Array.Resize(ref P6, execTime[6]); 
      Array.Resize(ref P7, execTime[7]); 
      Array.Resize(ref P8, execTime[8]); 
      Array.Resize(ref P9, execTime[9]); 
      Array.Resize(ref P0, execTime[0]); 

      //********************// 
      //*** Quantum Size ***// 
      //********************// 
      do 
      { 
       Console.Write("What's Your Quantum Size? "); 
       quantum = Convert.ToInt16(Console.ReadLine()); 
       if (quantum > execTime.Sum()) 
       { 
        Console.ForegroundColor = ConsoleColor.Red; // Red Color Text Below This 
        Console.WriteLine("Error => Your Quantum Size Should Be Less Then Total Execution Time."); 
        Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 
       } 
      } while (quantum > execTime.Sum()); 
      Console.ForegroundColor = ConsoleColor.Green; // Green Color Text Below This 
      Console.WriteLine("Success =>" + quantum + " Quantum Size Have Been Generated."); 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 

      Thread obj1 = new Thread(processRunning); 
      Thread obj2 = new Thread(interrupt); 
      obj1.Start(); // Start This Thread 
      obj2.Start(); // Start This Thread 

     } 

     static public void processRunning() 
     { 
      //***********************// 
      //*** Running Process ***// 
      //***********************// 

      Console.ForegroundColor = ConsoleColor.Green; // Green Color Text Below This 
      Console.WriteLine("Process Has Been Started Running...!!!"); 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 

      int i = 0; 
      while (i < execTime.Sum()) 
      { 
       if (i < P0.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 0"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P0.Length) 
         { 
          Console.WriteLine(P0[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       }     
       if (i < P1.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 1"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P1.Length) 
         { 
          Console.WriteLine(P1[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P2.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 2"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P2.Length) 
         { 
          Console.WriteLine(P2[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P3.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 3"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P3.Length) 
         { 
          Console.WriteLine(P3[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P4.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 4"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P4.Length) 
         { 
          Console.WriteLine(P4[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P5.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 5"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P5.Length) 
         { 
          Console.WriteLine(P5[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P6.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 6"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P6.Length) 
         { 
          Console.WriteLine(P6[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P7.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 7"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P7.Length) 
         { 
          Console.WriteLine(P7[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P8.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 8"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P8.Length) 
         { 
          Console.WriteLine(P8[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       if (i < P9.Length) 
       { 
        Thread.Sleep(1000); 
        int j; 
        Console.WriteLine("----------------------------------------"); 
        Console.WriteLine("Process Identification ID : Process # 9"); 
        for (j = i; j < i + quantum; j++) 
        { 
         if (j < P9.Length) 
         { 
          Console.WriteLine(P9[j]); 
         } 
         else 
         { 
          break; 
         } 
        } 
        Console.WriteLine("IR --> " + i); 
        Console.WriteLine("PC --> " + i); 
        Console.WriteLine("Flag --> " + flag); 
        Console.WriteLine("Last Instruction Address --> " + (j - 1)); 
        Console.WriteLine("Resume Instruction Address --> " + j); 
        Console.WriteLine("Algorithum --> Round Robin"); 
        Console.WriteLine("Quantum --> " + quantum); 
        Console.WriteLine("----------------------------------------"); 
       } 
       // Increment 
       i = i + quantum; 
      } 

      Console.ForegroundColor = ConsoleColor.Green; // Green Color Text Below This 
      Console.WriteLine("Process Has Been Completed Running...!!!"); 
      Console.ForegroundColor = ConsoleColor.White; // White Color Text Below This 
      Console.ReadLine(); 
     } 
     static public void interrupt() 
     { 
      // Intruppt 
      ConsoleKeyInfo c = Console.ReadKey(); 
      if (c.Key == ConsoleKey.Enter) 
      { 
       flag = 1; 
       // Should Pause The First Thread Here And Ask To Continue/Resume Or Kill 
      } 
      // Intruppt 
     } 
    } 

在这里,我想继续运行,直到processRunning();有人给输入interrupt();,然后它应该暂停processRunning();,等待恢复这也将被interrupt();函数所允许,所以它应该是什么逻辑/代码?

+0

是的,但是我想讲清楚,因为一些逻辑来源于背景也... –

+0

去它,我想要什么。下一次,我将重点... –

回答

1

有一对夫妇的事情,你应该在这里想到:

  1. 它存在一个Thread.Suspend机制描述here,但它是过时的和一个很好的理由,因为:

因为Thread.Suspend和Thread.Resume不依赖于被控制线程的协作,所以它们具有很强的侵入性,并且会导致严重的应用程序问题,例如死锁(例如,如果挂起一个拥有资源的线程另一个线程将n EED)。

所以,你可以使用机制和观望可能出现的死锁或其他同步错误或:

  • 你可以是同步逻辑转移到你想要的线程暂停时,processRunning()方法在你的情况下,做这样的事情:

    而(我< execTime.Sum()& &标志== 0)//尚未停止

  • 如果您想要更精细的粒度,即使在循环中间停止,而不是每次迭代,您都可以随心所欲地添加更多的检查。

    您还需要声明的标志为volatile因为该字段使用两个线程,需要这样标记:

    public static volatile int flag = 0;

    这是一个简单的例子:

    private static AutoResetEvent signal = new AutoResetEvent(false); 
        private volatile static bool interruptFlag; 
        private volatile static bool abortFlag; 
    
        private static void Process() 
        { 
         //replace true with your condition 
         while (true) 
         { 
          if (interruptFlag) 
          { 
           if (signal.WaitOne()) 
           { 
            if (abortFlag) 
            { 
             Console.WriteLine("exiting"); 
             return; 
            } 
           } 
          } 
    
          Console.WriteLine("doing work"); 
    
          //.. important work here 
         } 
        } 
    
        private static void Interrupt() { 
         ConsoleKeyInfo c = Console.ReadKey(); 
         if (c.Key == ConsoleKey.Enter) { 
          interruptFlag = true; 
          // Should Pause The First Thread Here And Ask To Continue/Resume Or Kill 
    
          c = Console.ReadKey(); 
    
          if (c.Key == ConsoleKey.Escape) 
          { 
           Console.WriteLine("Interrupting"); 
           abortFlag = true; 
           signal.Set(); 
          } 
          else 
          { 
           Console.WriteLine("Continuing"); 
           interruptFlag = false; 
           abortFlag = false; 
           signal.Set(); 
          } 
         } 
        } 
    
        static void Main() 
        { 
         Thread process = new Thread(Process); 
         process.Start(); 
    
         Thread interrupt = new Thread(Interrupt); 
         interrupt.Start(); 
    
        } 
    
    +0

    不错的提示,但它不恢复... :-) –

    +0

    更新回答:按Enter键=>暂停线程;之后按Escape =>停止线程;按除了Escape =>以外的任何内容。 –

    +0

    @MuhammadHassan让我知道这个解决方案是否适合你。 –

    -1

    尝试使用一个BackgroundWorker对象(System.ComponentModel)

    BackgroundWorker obj1 = new BackgroundWorker(); 
    obj1.DoWork += (dowork_s, dowork_e) => { 
        ProcessRunning(); 
    }; 
    obj1.RunWorkerCompleted += (completed_s, completed_e) => { 
        Thread.Sleep(1000); 
        if(StillRunning){ 
         worker.RunWorkerAsync(); 
        } 
        //if not still running, the thread will now terminate 
    }; 
    

    您可以通过调用obj1.Reset(暂停线程的执行),并通过obj1.Set恢复()。

    +0

    你能否按照我的要求简单理解...? –

    +0

    我已更新我的帖子,使执行更清晰一些。您可以用BackgroundWorker对象替换线程对象,并将它们设置为无限循环,直到指定标志,此时可以调用Reset()和Set来暂停和恢复。 – Jace

    +0

    意思是我想在'interrupt();'里面询问用户**像**你想恢复还是终止? [Y(简历)/ N(终止)] **所以要做什么和在哪里......?你能分享我更新的代码吗? –