polyanin
@polyanin
Golang, PHP & Symfony developer

Применяется ли во встроенной функции copy отложенное копирование?

Приветствую!
Работает ли при копировании слайса отложенное копирование (копирование при записи (copy on write)), тоесть копируется только дескриптор ресурса, без самого ресурса, и для владельцев ресурс становится разделяемым и доступным в режиме «только для чтения», но как только какому-нибудь владельцу потребуется модифицировать разделяемый ресурс, выполняется копирование ресурса и далее этот владелец работает со своей копией или сразу же происходит копирование с выделением памяти?
  • Вопрос задан
  • 153 просмотра
Решения вопроса 2
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
Отложенного копирования при копировании слайса нет.
Вот исходник функции, которая копирует слайсы.
https://golang.org/src/runtime/slice.go#L34
В комментарии к функции написано:
// makeslicecopy allocates a slice of "tolen" elements of type "et",
// then copies "fromlen" elements of type "et" into that new allocation from "from".


Исходный код функции на случай, если исходник не доступен

// makeslicecopy allocates a slice of "tolen" elements of type "et",
// then copies "fromlen" elements of type "et" into that new allocation from "from".
func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
	var tomem, copymem uintptr
	if uintptr(tolen) > uintptr(fromlen) {
		var overflow bool
		tomem, overflow = math.MulUintptr(et.size, uintptr(tolen))
		if overflow || tomem > maxAlloc || tolen < 0 {
			panicmakeslicelen()
		}
		copymem = et.size * uintptr(fromlen)
	} else {
		// fromlen is a known good length providing and equal or greater than tolen,
		// thereby making tolen a good slice length too as from and to slices have the
		// same element width.
		tomem = et.size * uintptr(tolen)
		copymem = tomem
	}

	var to unsafe.Pointer
	if et.ptrdata == 0 {
		to = mallocgc(tomem, nil, false)
		if copymem < tomem {
			memclrNoHeapPointers(add(to, copymem), tomem-copymem)
		}
	} else {
		// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
		to = mallocgc(tomem, et, true)
		if copymem > 0 && writeBarrier.enabled {
			// Only shade the pointers in old.array since we know the destination slice to
			// only contains nil pointers because it has been cleared during alloc.
			bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
		}
	}

	if raceenabled {
		callerpc := getcallerpc()
		pc := funcPC(makeslicecopy)
		racereadrangepc(from, copymem, callerpc, pc)
	}
	if msanenabled {
		msanread(from, copymem)
	}

	memmove(to, from, copymem)

	return to
}

Ответ написан
Сразу происходит копирование.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы