2016-03-28 64 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(終止)] **所以要做什麼和在哪裏......?你能分享我更新的代碼嗎? –