2012-08-08 2 views
3

VB2004에서 C#으로 VB2010을 사용하여 게임을 만들었습니다. 게임은 각 플레이어에 대한 스레드를 만들고 플레이어가 만든 LUA 코드를 실행합니다.스레드 스로틀 C#

각 LUA 코드는 스레드 차단하고, 스레드가 종료 된 경우에만 나는 컴퓨터가 현재 후 과열로 CPU 사용량을 제한 할

을 (루아 스크립트가 무한 루프를 포함한다) 종료한다 몇 시간 동안 100 % CPU로 실행.

스레드를 제어하지 않고 어떻게 조절할 수 있습니까? 쓰레드 매니저가 강제로 suspend/resume을 할 수 있기를 바랬지 만 그것들은 쓸모 없게되고 있습니다. 그리고 실행중인 LUA 코드를 중단시키기 때문에 예외를 던지기를 원하지 않습니다.

아이디어가 있으십니까?

감사합니다.

+1

본질적으로 메인 루프 인 C-Sharp 코드를 호출 할 수 있습니까? LUA에 고해상도 타이머가 있는지 확실하지 않지만 C-Sharp는 분명히 그렇습니다. 따라서 LUA의 주된 방법은 프레임 사이의 델타를 허용 할 수 있습니다. 그것을 스스로 계산합니다. – Matthew

+0

현재 작동하는 방식은 모든 게임 논리가 C-Sharp로 수행된다는 것입니다. LUA 스레드는 게임에 대한 정보를 얻고 LUA에서 호출 할 수있는 .NET 함수 (함수 매핑의 일종)를 통해 게임에 제어 정보를 반환 할 수 있습니다. 네가 묻는 것을 내가 이해하는지 모르겠다. 도움이 되니? – pcaston2

+0

LUA가 게임 로직의 대부분을 수행 할 것이라는 인상을 받았습니다. C-Sharp가 논리를 수행하면 LUA는 무엇을 추가합니까? – Matthew

답변

7

스레드의 우선 순위를 낮게 설정하면 시스템이 응답 속도가 빠르지 만 계속 100 % CPU를 사용하고 여전히 과열 될 수 있으므로 자세히 설명하지는 않겠습니다.

다른 포스터에서 언급했듯이 스레드에 작은 잠자기를 삽입해야합니다. 당신이 그들을 전혀 통제 할 수 없다면, 당신은 다른 것을 할 수 없습니다.

게임 API를 변경해야한다고 제안합니다.

코드를 루아 코드를 한 번 호출 한 다음 루아 코드를 무한 루프하는 것이 아니라 루아 코드가 "하나의 프레임 실행"기능을 갖도록 제안 할 것입니다. 그런 다음 무한 루프를 자신의 코드로 이동하고 "하나의 프레임 실행"기능을 반복적으로 호출합니다.

그런 식으로 잠자기를 삽입하고 기록을 추가하고 다른 모든 유용한 작업을 수행 할 수 있습니다.

+0

무한 루프를 초과하는 시간 초과 프레임의 경우 +1. 플래시 플레이어가 좋은 효과를냅니다. – spender

+1

@spender와 마찬가지로 Windows도 마찬가지입니다. –

+0

나는이 접근 방식을 어느 정도 좋아하지만 스레드를 계속 중단하고 재부팅하면 LUA 환경이 해체되어 사용자가 제한된 상태를 유지할 수 있습니다. 내가 할 일은 LUA 스크립트가 호출 할 수있는 함수를 추가하는 것이다. 이는 .NET 스레드를 잠자기 상태로 만든다. 마지막 호출 이후 얼마나 많은 시간이 만료되었는지 모니터링 할 수 있습니다. 사용자가 'hot'을 실행하면 스레드를 종료하고 오랜 시간 동안 절전 모드를 종료 한 다음 스레드를 재부팅 할 수 있습니다. 이로 인해 사용자는 내가 생각하는 처리에 대해 합리적이 될 수밖에 없습니다. 나는 이것을 줄 것이다. – pcaston2

1

무한 루프의 스레드가 너무 많은 CPU를 소비하지 않도록하는 일반적인 방법은 각 반복에서 잠자 게 만드는 것입니다 (일반적으로 5ms가 트릭을 수행합니다). 이렇게하면 다른 자원이 cpu를 사용할 수 있도록 시스템 시간을 제공합니다. 또한 스레드에 우선 순위를 지정하지 마십시오.

+0

"LUA 코드가 스레드를 차단하고있는 경우"얼마나 도움이 될지 모르겠습니다. LUA 코드가 실행 중이고 Thread.Sleep()을 호출 할 수 없다고 가정합니다. –

+0

@Peter "LUA 스크립트에는 무한 루프가 있어야합니다"라는 부분이 있습니다. 무한 루프를 포함하는 코드는 sleep 함수를 호출해야합니다. –

+0

BTW. Thread.Sleep은 시스템 "퀀텀 (quantum)"에 의해 정의 된 입상 성을가집니다. 수면 (5)은 기본적으로 일어나지 않을 것입니다. 시스템에 따라 Sleep (20)과 동일 할 수 있습니다. 루프 된 CPU 바운드 스레드가있는 경우 Thread.Sleep (1)을 사용하여 다른 스레드에 CPU를 포기할 수 있습니다. 루프가 없거나 Thread.Sleep을 호출 할 수있는 특정 포인트가없는 경우이 Sleep 개념은 작동하지 않습니다. –

1

실행 스레드의 스케줄링을 제어하는 ​​고전적인 방법은 Fibers를 사용하는 것입니다.

그러나 Fibers는 WIN32 API의 기본 기능입니다. 가장 가까운 곳에서 C#을 사용하면 반복기를 사용할 수 있습니다. 반복자를 호출하여 다음 작업을 수행하기를 원한다.

두 번째 링크 참조 ... 관리되지 않는 네이티브 Fibre API를 사용하여 일부 .NET coroutines을 래핑하는 방법 또는이 스레드에서 실행중인 LUA 코드가 기본이며 사용자가 소스 코드 ... ConvertThreadToFibre를 사용하여 제어권을 얻을 수 있습니다. 파이버 API 호출에 대한 interop을 사용하여 일정이 잡히면 언제 결정할 수 있습니다.

아니면 계속하고 몇 가지 작업을 (할 수있는 때 플레이어 스레드에 신호를 이벤트를 사용하는 스케줄링 스레드를 가질 수 코드의 일부는/네이티브 C++로 일부는 C 번호는 각이 동일한 참조 할 수있는 경우 이벤트 핸들 .... 그냥 코드의 각 비트에서 WIN32API 또는 .NET API를 사용).

+0

하지만 불행히도 C#/.NET에는 광섬유가 없습니다. –