유니티
c# lock 키워드
공대녀J
2022. 10. 4. 15:41
public class PacketQueue
{
struct PacketInfo
{
public int offset;
public int size;
};
//데이터가 삽입될 버퍼
private MemoryStream m_streamBuffer;
//패킷 정보 관리 리스트
private List<PacketInfo> m_offsetList;
//총 데이터의 오프셋
private int m_offset = 0;
//lock 파라미터에 사용될 임의의 객체 생성. 설명에 추가.
private Object lockObj = new Object();
public PacketQueue()
{
m_streamBuffer = new MemoryStream();
m_offsetList = new List<PacketInfo>();
}
public int Enqueue(byte[] data, int size)
{
PacketInfo info = new PacketInfo();
info.offset = m_offset;
info.size = size;
lock(lockObj)
{
// m_offsetList도 lock 구문에 함께 삽입하여 패킷 데이터 버퍼의 정보와 동기화
m_offsetList.Add(info);
m_streamBuffer.Position = m_offset;
// data, position으로부터의 offset, 데이터 크기를 매개변수로 갖는다.
m_streamBuffer.Write(data, 0, size);
m_streamBuffer.Flush();
m_Offset+=size;
}
//삽입된 데이터의 사이즈 반환.
return size;
}
lock으로 설정된 블록을 한번에 하나의 스레드에서만 실행할 수 있도록 해준다.
-> 다른 스레드는 lock이 해제될 때까지 대기한다.
lock이 유지되는 동안 lock을 보유하는 스레드는 lock을 다시 획득하고 해제할 수 있다.
lock 파라미터에는 임의의 객체를 사용할 수 있으며, 주로 object 타입의 private 필드를 지정한다고 한다.
lock 파라미터에 넣어주는 임의의 객체는 lock을 하기 위한 열쇠로 생각하면 좋다.
따라서, lock 파라미터에 들어갈 객체는
1. 전용 개체 인스턴스 (예 : private readonly Object lockObj = new Object(); )
2. 코드의 관련 없는 파트에서 잠금 개체로 사용되지 않을 가능성이 있는 다른 인스턴스
교착 상태와 잠금 경합 에러가 발생할 수 있기 때문에,
1. this
2. Type 형 인스턴스
3. 문자열 인스턴스
는 lock 파라미터로 넣지 않도록 한다.