아마 오해가 있습니다.이 함수는 c- 배열이지만 메모리보기 슬라이스를 반환하지 않습니다. 당신은 나를 믿을 필요가 없습니다. nogil
을 삭제하고 cython을 호출하여이를 확인할 수 있습니다. 생성 된 * .c 인 파일에서는이 함수의 C-서명, __Pyx_memviewslice
중요한 부분이되고 볼 수 있습니다
static CYTHON_INLINE __Pyx_memviewslice __pyx_f_4file_array_test(CYTHON_UNUSED double *__pyx_v_x)
이 메모리보기 파이썬 객체입니다, 그래서는 가비지 컬렉터에 등록해야하며, 따라서 Global Interpreter Lock이 필요합니다. 이것이 "Gil없이 허용되지 않는 작업"오류 메시지를 보는 이유입니다.
- "nogil"로 그것을 할 정말 그렇게 중요하다
그래서 당신은 적어도 세 가지 옵션이 있습니다? 그렇지 않다면 그냥 버리십시오. 가장 간단한 솔루션 인 단점 : 성능이 저하 될 수 있습니다.
- 실제 C 배열을 사용하십시오 (예 :
int *res = (int *) malloc(2*sizeof(int))
). 그것은 빠르지 만, 단점 : 당신 스스로 메모리를 관리해야합니다.
- C++과
std::vector<int>
을 사용하면 장점은 더 이상 메모리를 관리 할 필요가 없지만 C++로 전환해야한다는 것입니다.
가능성 (1)의 개선 (이 실제 코드 예제하지만, 힘에 대한 많은 차이를하지 않습니다) 만 필요 마지막 행을 위해 길을 aquire하는 것입니다
cdef inline int[:] array_test(double *x) nogil:
cdef int output[2]
output[0]=1
output[1]=9
with gil:
return output
cdef inline void array_test(double *x, int[:] output) nogil:
0 : 영업 이익은 제안함에 따라 는
, 추가 가능성에 함수의 서명을 변경하는 것
트릭 여기 : array_test
은 더 이상 결과 메모리보기 슬라이스를 만들지 않으며 가비지 수집기에 등록 할 필요가 없으므로 "nogil"이 가능합니다.
array_test
의 호출이 더 복잡해지고 호출자가 output
메모리보기를 만들기 위해 gil을 가져야하는 것처럼 약간의 단점이 있습니다. 그러나 호출자는 어떤 종류의 데이터 구조에서 결과를 저장해야하는지 (numpy 배열 또는 다른 것)를 결정할 수 있다는 이점도 있습니다.
출처
2017-10-11 19:56:52
ead
옵션을 제공해 주셔서 감사합니다. 문제를 회피 할 수있는 또 다른 방법은 함수를 무효화하고 추가 빈 입력 배열을 수정하는 것입니다. – user3433489
@ user3433489 얼마나 간단합니까! 이걸 생각하지 않았어 ... – ead