문제

다음을 결정하는 방법이 있습니까? free() 특정 메모리 블록 포인터를 호출하면 실패할까요?

다음과 같은 상황이 있습니다. 공유 리소스에 액세스하는 스레드가 실패합니다. ...하는 동안 그것 5월 상기 자원을 풀어주는 상태에있었습니다. 이제이 공유 리소스를 정리할 수있는 안전한 방법을 고안해야합니다.

물론 나는 자원의 소유권을 할당했다. 정상 사례이지만 앞서 언급 한 한계 사례는 어떻습니까?

업데이트 : 추가 동기화 메커니즘을 사용하는 경우 더 많은 청소를하고 ~할 것 같다 추가 제한 조건이 포함되었습니다. 가능하다면 제한/피하고 싶습니다.

해결: 나는 마침내 재면 작용을 수행하는 데 정착했다. 모든 기고자들에게 감사합니다. 너희들 락!

도움이 되었습니까?

해결책

나는 이것을 포함하여 모든 종류의 시도를 보았습니다.

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

유형의 펀드 포인터가 다양한 플랫폼을 깨뜨리는 데 드리 렌더링 할뿐만 아니라 '이 예제를 연결하는'모든 기존 기능 (컴파일 된 LIBS 포함)에서 모든 단일 포인터를 초기화하고 무료 및 재직하는 경우에만 작동 할 수 있으며 C 라이브러리와 함께 C 라이브러리와 함께 작동합니다. 동일합니다.

그런 다음 최적화를 처리하고 무료 스레드 안전 문제를 잠그십시오. 바!

요컨대, 단일 함수로 할당 한 내용을 추적 할 수 없다면 해당 기능을 다시 수행 할 시간입니다. 충분히 .. 그리고 당신은 더 안전한 무료 ()의 필요성이 빠르게 사라질 것임을 알게 될 것입니다. Valgrind 지원하는 플랫폼에서 작업하는 경우 친구입니다. 당신의 태그에 따르면, 그것은 정말로 당신의 친구입니다 :)

또는 a Malloc () 그 스포츠 쓰레기 수집 자신의 비용으로, 물건을 할당하고 무료 ()를 모두 제거하는 방법에 따라. 그 후, 디버깅은 거의 말기 흥미로워집니다.

바라건대, 당신은 재 인자를 위해 꺼져 있습니까? 상호 배제로 문제가있는 것처럼 보이지만 다시 요점으로 돌아갑니다. 즉, Free () 블록 앞에 선을 표시하거나 잠금을 얻으려고 할 때 실패하십시오.

다른 팁

나는 당신이 원하는 것을하는 순응 인터페이스가 있다고 생각하지 않습니다.

그러나 몇 가지 트릭을 생각할 수 있습니다. 실패하기 쉬운 스레드가 래퍼를 호출 할 수 있습니다. free() 대신에 free() 곧장; 래퍼는 주소 또는 마지막 몇 주소를 저장하여 블록이 릴리스되었는지 확인할 수 있습니다. 또한 신호를 차단하거나 중요한 섹션을 설정하거나 다른 스레드를 방해 할 수있는 모든 것을 처리 할 수도 있습니다.

업데이트: 종료/청소 전에 죽어가는 실 이이 메모리를 해제합니까? 나는 정상 상태에서 해제 될 필요가없는 메모리를 위해 Malloc 프론트 엔드 (속도 최적화)를 자주 썼습니다. 스레드가 자체적으로 설정되는 경우 스레드가 시작되기 전에 메모리를 malloc 할 수 있으며 스레드가 동적 블록의 끊어지지 않고 끊어지지 않은 조각을 건네주는 프론트 엔드를 호출하게 할 수 있습니다. 더 빨리 실행되면 스레드가 죽으면 한 번에 전체 블록을 풀 수 있습니다. 여기서 일반적인 아이디어는 실패가 발생하기 쉬운 스레드가 다음에 요소를 정리할 수있는 서비스를 호출하여 메모리를 얻는 것입니다.

또 다른 아이디어 : 스레드 당 힙은 어떻습니까? 스레드가 자신의 힙에서 생애 동안 필요한 메모리를 할당하도록 설득 될 수 있다면, 스레드가 부모와 다시 합류 할 때 스레드 힙을 해방하도록 정리 작업을 멋지게 구성 할 수 있습니다.

나는 당신이 요구하는 일을 정확히 할 수있는 방법이 없다고 생각합니다.

문제는 죽어가는 실이 죽었을 때 어떤 상태가 있었는지 결정할 방법이 없다는 것입니다. 단순히 무료 ()에게 전화를 걸어 더 이상 얻지 못했습니까? Free () 무료 목록에 블록을 다시 추가 했습니까? 당신은 말할 수 없습니다.


스레드가 이런 식으로 죽는 것이 정말 드문 조건이라면 (따라서 끊임없는 메모리를 주위에 두는 것이 좋습니다. 당신은 그것을 사용하지 않는 것을 알고 싶어합니다) 다음 (Windows 호출 사용)은 메모리와 '마크를 사용합니다. '다른 스레드에게 무료로 :

void* ptr;
...
void* desiredPtr = ptr;
if(InterlockedCompareExchangePointer(&ptr, NULL, desiredPtr) == desiredPtr)
  free(desiredPtr);

이것이하는 일은 하나의 스레드 만 메모리를 제거하려고하는지 확인하고 주소를 null로 설정하기 전에 다른 스레드가 자유를 시도하지 않습니다 ().


메모리가 때때로 주위를 유지하는 것이 용납 할 수없는 경우 가장 좋은 방법은 메모리를 자유롭게하는 것만으로도 별도의 스레드를 갖는 것일 수 있습니다. 그런 다음 다른 스레드는 프리 메모리 스레드에 대한 무료 요청을 대기열 할 수 있습니다. 프리 메모리 스레드는 너무 간단하기 때문에 결코 죽지 않아야하며 자유 작업을 제대로 완료 할 수 있습니다.

당신이 전화하는 경우 free a 유효한 포인터, 나는 그것이 어떻게 실패할지 모르겠다. 실패한 경우 유효하지 않은 포인터 때문입니다.

공유 메모리에 대한 액세스를 동기화하는 것 외에도 ( 뮤텍스, 예를 들어), 소유권도 이중 자유와 같은 사례를 피하기 위해 명확해야합니다. 이중 무료는 둘 이상의 스레드가 유효한 포인터를 가질 때이지만 둘 이상의 스레드가 메모리를 제거하려고 시도합니다. 두 번째 스레드는 널이 아닌 포인터가 있지만 더 이상 유효하지 않습니다.

C/C ++의 메모리 문제가 발생하면 다음과 같은 메모리 라이브러리를 사용해 볼 수 있습니다. . 이와 같은 메모리 라이브러리는 기기 및 각 메모리 할당을 초기화합니다. 메모리를 풀기 전에 메모리 포인터가 먼저 유효한지 확인하고 버퍼 오버런 오류가 없었습니다. 내장 Malloc/Free를 간단히 바꿀 수 있으므로 코드 변경이 없어야합니다. 또한 라이브러리는 메모리 누출, 덮어 쓰기 및 유효하지 않은 참조를 찾는 데 도움이 될 수 있습니다.

문제를 해결하기위한 또 다른 전략은 리소스 정리를 하나의 스레드로 중앙 집중화하는 것입니다. 자원으로 스레드가 완료되면 쓰레기 수집가 실.

물론, 계획 C가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top