>  기사  >  백엔드 개발  >  C#Thread에 대한 자세한 소개를 조금씩

C#Thread에 대한 자세한 소개를 조금씩

黄舟
黄舟원래의
2017-03-20 13:17:171854검색

C#의 Thread를 이용하여 간단한 타이머를 만들었습니다. 45분 후에 휴식을 취할 수 있도록 45분 후에 음악 안내가 울립니다.

처음에 사용한 TimeSpan 빼기 방법은 Thread의 시작 함수에 다음과 같이 작성되어 있습니다.

  1. public void CountTime()
    {
                
       while (true)
       {
          TimeSpan tsNew = new TimeSpan(DateTime.Now.Ticks);
          TimeSpan tsIn = tsNew - tsOld;
          if (tsIn.Minutes >= 1)
          {
        
             while (true)
             {
                 TimeSpan tsNewer = new TimeSpan(DateTime.Now.Ticks);
                 TimeSpan tsIner = tsNewer - tsNew;
                 if (tsIner.Minutes >= 10)
                 {
                    //十分钟后线程重启
                     tsOld = tsNew;
                     break;
                 }
             }
             
           }
       }
    }

나중에 이 방법을 발견했습니다. 너무 비효율적입니다. 물론 Thread.Sleep(20)을 사용하면 CPU 사용 시간을 줄일 수 있습니다. 실제로 Thread.Sleep(20)을 중간에 추가하면 CPU 소비를 크게 줄일 수 있습니다. 나중에 나는 C#의 스레드에 스레드를 일정 시간 동안 기다리게 할 수 있는 자체 함수인 Join()이 있다는 것을 발견했습니다. 호출 방법은 다음과 같습니다

th.Join(new TimeSpan(hours, Minutes, Second)); 대기 기간 동안 스레드는 WaitSleepJoin상태입니다.

물론 Thread.Sleep(millionseconds)을 호출할 수도 있습니다. 여기에 Sleep과 Join의 차이점이 있습니다.

스레드가 Sleep을 실행할 때 시스템은 실행 큐 종료 잠시 후 슬립이 끝나면 시스템은 클럭 인터럽트를 생성하여 스레드가 실행 큐로 돌아가 스레드 실행을 재개하도록 합니다. Sleep 메소드의 매개변수가 0이면 대기 중인 다른 스레드가 실행될 수 있도록 이 스레드를 일시 중단해야 한다는 의미이며, 여기서는 CPU가 제어권을 재분배하며 방금 실행된 프로그램일 수도 있습니다. 이런 방식으로 CPU 사용량은 항상 100%가 됩니다. 인터페이스가 작동하지 않는 경우도 있지만 여전히 마우스를 움직일 수 있습니다. Timeout.Infinite인 경우 Thread.Interrupt를 호출하는 다른 스레드에 의해 중단되거나 Thread.Abort에 의해 중단될 때까지 스레드가 휴면 상태라는 의미입니다.
 
상위 스레드가 하위 스레드보다 먼저 끝나면 하위 스레드는 상위 스레드가 끝나는 동시에 강제로 종료됩니다. Thread.Join() 메서드를 사용하면 상위 스레드가 하위 스레드가 끝날 때까지 기다리게 됩니다. Join 메서드에는 반환 값이 있습니다. 값이 true이면 스레드가 종료된다는 의미입니다. false인 경우 해당 시간 동안 대기한 후에도 스레드가 종료되지 않았음을 의미합니다. 스레드가 시작되지 않은 상태인 경우 Join()을 호출하면 ThreadStateException 예외가 발생합니다. 스레드가 종료된 경우 이 함수를 호출하면 즉시 반환 값을 가져옵니다.

예를 들어 다음 메인 프로그램

...
ThreadStart st = New ThreadStart(fun);
Thread th = new Thread(ThreadStart st);
th.Start();
Application.Exit();
...
 
//下面是fun函数
void fun()
{
    while(true)
    {
            ...
    }
}

이 프로그램의 유일한 문제점은 메인 프로그램 이후에 프로그램이 종료되고 슬레이브 스레드가 종료됩니다. 아직 끝나지 않았습니다. (이 슬레이브 스레드가 너무 불쌍해요...)

그런데 스레드의 몇 가지 상태는 다음과 같습니다.

생성: 새로운 프로세스가 생성되면 해당 프로세스에 대한 스레드도 생성됩니다. 스레드는 새로운 스레드를 생성할 수도 있습니다.

준비: 스레드가 프로세서를 제외한 모든 리소스를 확보했습니다.

실행 중: 스레드가 프로세서에서 실행 중입니다.

차단: 이벤트를 기다리는 동안 스레드가 일시 중지됩니다.

종료: 스레드가 완료되었습니다.

그러나 C# 스레드에는

Aborted, AbortRequested, Background, Running, Stopped, StopRequested, Suspended, SuspendRequested, Unstarted, WaitSleepJoin과 같은 몇 가지 상태가 더 있습니다.

Abort()는 ThreadState.AbortRequested를 발생시킵니다. Abort()를 호출하는 스레드가 제어권을 얻은 후 ThreadState.Aborted를 발생시킵니다. AbortRequested와 Aborted의 차이점은 하나는 중지되고 다른 하나는 중지되지 않는다는 것입니다. . 중지됨은 스레드가 종료되었음을 의미합니다. 그러나 여러 번 시도하고 테스트한 결과 Abort() 함수가 호출되면 스레드 상태가 중지됨으로 변경되는 것을 발견했습니다. Aborted 상태로 변경하는 방법은 아직 연구중입니다. 다른 주도 비슷하다. 해당 함수를 호출하면 해당 상태 요청이 생성되며 해당 상태를 가져오는 데 시간이 걸립니다. Unstarted는 Start() 함수가 호출되지 않았다는 뜻이고, Running은 Start()나 Resume() 함수를 호출한 결과이다. WaitSleepJoin이 I/O를 기다리고 있거나 Join() 메서드를 호출하고 있습니다. 여기서 Join()과 Sleep() 메서드의 차이점은 Join() 호출 스레드 상태가 WaitSleepJoin으로 들어가고 Sleep() 호출 스레드 상태가 여전히 실행 중이라는 것입니다.

스레드를 일시 중단하는 메서드는 Suspend()입니다. 이 메서드를 호출하면 스레드는 SuspendRequest 상태가 됩니다. Suspended()가 호출된 후에도 스레드가 여전히 Join() 메서드를 실행 중인 경우 Suspended()는 스레드를 일시 중단하기 전에 스레드가 안전 지점에 도달해야 하기 때문입니다. SuspendRequested|WaitSleepJoin 입니다. 그러나 여기 조인의 시계는 여전히 계산 중입니다. 그래서 조인 횟수를 일시 중지하는 방법을 아직 모르겠습니다. 물론 조인을 사용하지 않고 스레드를 완전히 일시 중지하는 문제도 해결할 수 있습니다. 이제 스레드가 여전히 실행 중이기 때문에 어떤 Suspended() 함수가 무엇을 하는지 이해할 수 없습니다. Suspend()를 호출한 후 스레드가 다시 재개되도록 허용하는 Suspend() 및 Resume() 메서드의 사용이 이제 더 이상 사용되지 않는다는 점도 언급할 가치가 있습니다. 이유는 매우 간단합니다. 왜냐하면 이 두 메소드는 다른 스레드에 의해 실행되고, 다른 스레드는 특정 클래스의 구조와 같이 Suspend() 중인 스레드의 상태를 정확하게 알 수 없기 때문입니다. 기능 실행기간, 파기 등 따라서 이 기능을 동기화에 사용하는 것은 위험합니다.

또한 Thread.Sleep(n)의 n은 시간을 정확하게 제어할 수 없다는 점에 유의해야 합니다. 스레드하는 데 시간이 얼마나 걸리는지 생각하면 이 컨트롤에 문제가 있습니다. 현재 스레드가 포그라운드 스레드인 경우 Thread.Sleep(n)은 종료되기 전에 n보다 커야 합니다. 백그라운드 프로세스인 경우 메인 프로그램이 종료되면 이 스레드는 더 이상 깨어날 수 없습니다... 비참합니다... 따라서 일반적으로 Thread.Sleep() 함수를 사용하지 않는 것이 좋습니다. 또한, Sleep 기능은 동기화에 사용할 수 없습니다. Peter는 프로그램의 Sleep 기능이 잘못된 설계를 나타낸다고 말했습니다.


위 내용은 C#Thread에 대한 자세한 소개를 조금씩의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.