2016-12-03 2 views
1

Go에서 슬라이스를 사용하는 FIFO 대기열의 구현을 보았습니다. 항목이 대기열에서 나갈 때 기본 배열을 재 할당하지 않고도이 메모리를 확보 할 수 있습니까? 이것이 발생하지 않으면 대기열에 많은 양의 메모리가 누출되는 것 같습니다.Go에서 슬라이스를 사용하는 큐 구현

type queue 
{ 
    []int 
    int head 
} 

func (q *queue) enqueue(val int) { 
    q = append(q, val) 
} 

func (q *queue) dequeue() int { 
    return (*q)[q.head++] 
} 

배의 무리 디큐/대기열을 호출 한 후, 슬라이스를 underying 배열의 낮은 인덱스는 더 이상 사용할 수 있지만 나는 그들이하거나 해제 할 수있는 방법을 확실하지 않다 : 이것은 내가 의미없는 것입니다. 누군가 포인터를 사용하지 않는 적절한 큐 구현을 가리킬 수 있으며 이와 같은 메모리 누출 또는 성능 문제가 있습니까? 또는 이것이 어떻게 효과가 있을지에 대한 설명도 인정 될 것입니다.

당신은 원형 버퍼를 사용할 수 Plamen

+0

우선 동시성을 원할 경우 이미 냄새가 나는 방법으로 뮤텍스 잠금이 필요합니다. 채널은 기본적으로 스택 복사본이므로 큐를 사용하여 대기열을 처리합니다. GC는 사용 후 정리합니다. – eduncan911

+0

스레드 안전에 관심이없는,이 질문에 대한 메모리 관리. 큐를 구현하기 위해 채널을 사용하는 것은 일상적인 스케줄링을 위해 긴밀히 묶여 있고 전체 프로그램을 끊을 수 있기 때문에 내가 읽은 것에서 나쁜 생각입니다. 가장 좋은 경우에는 비효율적입니다. 이 책은 내가 읽은 책입니다. https://www.amazon.com/Programming-Language-Addison-Wesley-Professional-Computing/dp/0134190440 –

+0

위의 코드는 구현이 아니며 단순히 내 질문을 설명하기위한 것입니다. –

답변

1

을 주셔서 감사합니다. wikipedia :

순환 버퍼, 순환 큐, 순환 버퍼 또는 링 버퍼는 단일 고정 크기 버퍼를 종단 간 연결처럼 사용하는 데이터 구조입니다. 이 구조는 데이터 스트림을 버퍼링하기 쉽습니다.

...

원형 버퍼링은 최대 크기를 고정 한 큐에 대한 좋은 구현 전략을합니다. 대기열에 대해 최대 크기를 채택해야한다면 순환 버퍼는 완전히 이상적인 구현입니다. 모든 대기열 작업은 일정 시간입니다. 그러나 원형 버퍼를 확장하려면 메모리를 이동해야하며 이는 상대적으로 많은 비용이 듭니다. 임의로 확장되는 대기열의 경우 연결된 목록 방식이 대신 사용될 수 있습니다.

여기에 구현 한 패키지는 https://github.com/eapache/queue입니다.

사용 사례에 따라 채널이 대기열을 구현하는 좋은 방법이기도합니다. 차단하지만 기본값을 사용하여 select를 사용하면 동작을 피할 수 있습니다.