구조체 "타일"이 포함 된 거대한 배열이 있습니다. 프로그램 메신저는 2D 게임이며, 다른 플레이어 (다른 스레드에 의해 처리됨)가 동시에 같은 타일에 위치를 기록하는 것을 원하지 않으며 두 가지가 궁금합니다. 두 개의 스레드가 안전하게 동시에 두 개의 서로 다른 위치에 쓸 수 있습니까?이 배열의 하나의 인덱스 만 잠그는 효과적인 방법이 있습니까?구조체의 배열, 멀티 스레딩, 다른 인덱스에 동시에 쓸 수 있습니까?
답변
예, 다른 스레드에서 동시에 다른 위치에 쓸 수 있습니다.
잠금을 수행하려면 잠금 배열을 작성하고 간단한 해싱 기술을 사용하여 작성중인 위치에 따라 잠금을 선택해야합니다. 예를 들어 :
class TileArray
{
private static readonly int numLocks = 16;
private object[] locks = (from i in Range(0, numLocks) select new object()).ToArray();
private Tile[] tiles = hugeTileArray();
...
public Tile this[int i]
{
get { return tiles[i]; }
set
{
lock (locks[i % numLocks])
tiles[i] = value;
}
}
}
이것은 잠금 엄청나게을 만들 필요가 피할 수 있지만, 여전히 최소한으로 잠금 경합을 유지합니다. 프로파일 링에 따라 numLocks를 위 또는 아래로 설정할 수 있습니다. 효율적인 모듈로 계산을 위해서는 2의 제곱을 유지하십시오.
최종 세부 사항 : 앨리어싱 효과에주의하십시오. 예를 들어, 16의 배수가 약간의 이상한 이유로 스레드에서 매우 인기가있을 수 있습니다.이 경우 경합이 지붕을 통과하게됩니다. 이 경우 더 강력한 해시가 필요합니다. 아마도 (uint)i.GetHashCode() % numLocks
이 실행될 것입니다. 그러나 무엇을 Int32.GetHashCode
이 수행할지 모르겠습니다. 숫자 자체를 반환 할 수 있습니다. 이것이 실패하면 Bob Jenkins에서 훔칠 수 있습니다.
원하는 작업을 기본적으로 지원하지 않습니다. 여러 스레드가 동시에 같은 배열에 액세스 할 수 있지만 동기화 등을 통해 데이터 일관성을 처리해야합니다. 따라서 인덱스 별 잠금 (데이터베이스가 트랜잭션에서 수행하는 것과 유사)을 구현하는 것이 가능하지만, 이것이 사용자가하려는 작업에 적합한 방법인지 확신 할 수 없습니다. 배열을 사용하여 시작하는 이유는 무엇입니까?
필자는 필요한 빠른 액세스가 있어야한다고 생각하고 2D 게임이므로 X 및 Y 좌표를 인덱스로 사용할 수 있습니다. – Alle
나는 lock statement을 사용하여 배열에 액세스하고 스레드간에 공유되는 코드 스레드를 안전하게 만들 수 있다고 생각합니다.
잠금을 명시 적으로 사용하지 않고도 읽고 쓸 수있는 Interlocked.CompareExchange
함수를 사용할 수 있습니다. 당신이 클래스에 Tile
구조체를 변환해야합니다 물론
public class Example
{
private Tile[] m_Array;
public Tile this[int index]
{
get { return Interlocked.CompareExchange(ref m_Array[i], null, null); }
set { Interlocked.CompareExchange(ref m_Array[i], value, m_Array[i]); }
}
}
이 작업을 수행 할 수 있습니다.
- 1. 다른 스크립트를 멀티 스레딩
- 2. 동시에 구조체의 다른 필드를 업데이트하는 것 - 안전합니까?
- 3. 동시에 액티비티와 서비스가 DB에 쓸 수 있습니까?
- 4. C 멀티 스레딩 원점
- 5. 멀티 스레딩 C 언어의 구조체 배열
- 6. 멀티 스레딩
- 7. Java의 멀티 스레딩
- 8. 정적 메서드 및 멀티 스레딩
- 9. iPhone "멀티 스레딩"질문
- 10. PHP에서 멀티 스레딩
- 11. 멀티 스레딩 루프 효과가 있습니까?
- 12. dotNet의 잠금 및 멀티 스레딩
- 13. 멀티 스레딩 문제
- 14. Bash의 멀티 스레딩
- 15. C++ volatile 멀티 스레딩 변수
- 16. 구조체의 배열 - 구조체?
- 17. 멀티 스레딩 C# 사용 방법?
- 18. 멀티 스레딩 및 멀티 태스킹
- 19. iPhone : 멀티 태스킹, 멀티 스레딩?
- 20. LINQ Changeset 멀티 스레딩
- 21. 멀티 스레딩 및 위임자 실행
- 22. C 구조체의 배열
- 23. Initilize 구조체의 배열
- 24. iframe을 사용하는 멀티 스레딩
- 25. 동시에 파일에 데이터를 읽고 쓸 수
- 26. 멀티 스레딩 솔루션
- 27. 멀티 스레딩 참조?
- 28. 멀티 스레딩 질문
- 29. JavaFX 멀티 스레딩
- 30. red5의 멀티 스레딩
아, 고마워. :) 동등한 크기의 물체 배열을 가지고 자물쇠를 잡는 것에 대해 생각해 보았지만, 더 이해가됩니다. – Alle
그런 식으로하면 1 차원 배열로 변경해야합니다. 그렇습니까? – Alle
@Alle : 원칙은 위치의 해시를 생성하는 것입니다. 1 차원 배열이라면'i % numLocks'의 간단한 문제입니다. 그러나 이것은 특별한 경우입니다. 2 차원 배열을 사용하는 경우 'i <0x10000'인 동안 'hash (i << 16 + j) % numLocks' (여기서'hash '는 임의의 올바른 정수 해시 함수)를 사용할 수 있습니다. –