2017-02-02 1 views
-1

나는 리눅스에서 클론()을 사용하여 C에서 스레드를 구현하려고 시도하고 있지만, 이상한 문제가 있습니다.리눅스 클론이 "죽이기"메인 스레드

첫째, 여기 내 뮤텍스 기능은 다음과 같습니다

void mutex_lock(int* lock) { 
    while (!__sync_bool_compare_and_swap(lock, 0, 1)) { 
    syscall(SYS_futex, lock, FUTEX_WAIT_PRIVATE, 1, NULL, NULL, 0); 
    } 
} 

void mutex_unlock(int* lock) { 
    if (__sync_bool_compare_and_swap(lock, 1, 0)) { 
    syscall(SYS_futex, lock, FUTEX_WAKE_PRIVATE, 0, NULL, NULL, 0); 
    } 
} 

그리고 내 코드에서 내 스레드 구조체

typedef int (*ThreadCallback)(void*); 

typedef struct Thread { 

    void* alloc; 

    char lockSpace[sizeof(int) * 2]; /* Used to align lock pointer properly */ 
    int* lock; 
    int started; 
    int tid; 

    void* stack; 
    size_t stackSize; 

    ThreadCallback fn; 
    void* args; 

}* Thread; 

, 내가 나중에

void* start = memAllocThread(sizeof(void*) + sizeof(struct Thread) + TH_STACK_SIZE); 
if (start == NULL) { 
    return TH_MEM; 
} 

struct Thread* th = start + TH_STACK_SIZE + sizeof(void*); 
th->alloc = start; 

size_t lockSpacePtr = (size_t)(th->lockSpace); 
lockSpacePtr += 4 - ((lockSpacePtr % 4) % 4); /* To align ptr on? at? 4 bytes */ 

th->lock = (int*)lockSpacePtr; 
*th->lock = 0; 
th->started = 0; 

th->stack = start + TH_STACK_SIZE; 
th->stackSize = TH_STACK_SIZE; 

th->fn = fn; 
th->args = args; 
를 사용합니다 할당과 스레드 구조체를 초기화

"TH_STACK_SIZE", "fn"및 "args"는 각각 "0x7fff" "ThreadCallback"및 "void *"입니다.

이제 스레드 구조체를 초기화하고 PortAudio 및 기본 스트림을 하나의 입력 채널과 0 출력 채널로 초기화합니다. 후, 이제 그럼 난 내 스레드

THResult thStart(struct Thread* th) { 

    int tid; 

    mutex_lock(th->lock); 

    if (th->started) { 
    mutex_unlock(th->lock); 
    return TH_RUNNING; 
    } 

    tid = clone(_thFunction, th->stack, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_IO | CLONE_SIGHAND | CLONE_THREAD, th); 

    if (tid < 0) { 
    mutex_unlock(th->lock); 
    return TH_CLONE_ERRNO; 
    } 

    th->started = 1; 
    th->tid = tid; 

    mutex_unlock(th->lock); 
    return TH_OK; 
} 

"INT의 _thFunction (무효 *)"현재 비어 시작 (충전 할 때, 그것은 TH-> FN 시작해야한다,하지만 문제는 여기에 없다)

을 그리고 Pa_StartStream()에 대한 호출, 내가 원하는 것을 쓸 수있다. 실행되지 않는다. (그런데 코드에 어떤 것이 퍼지면 printf는 자연 스럽다.) I

  • 내가 Pa_StartStream을 제거
  • 추적 세그먼트 위반하는을 시도 : 그것은 작동하지만, printf와 아직도 내가 내 스레드의 시작을 제거하고 모든

어떤 생각 괜찮다고

  • 너무 야생했다 ?

    는 편집 1 :

    생성 된 스레드가 종료
    • , 프로그램이 종료
    • GDB가 그것에 대해 아무것도 말하지 않는다, 나는 그것을 파괴에
  • +2

    'printf' (및 다른 많은 라이브러리 함수)는 호출자가 일부 "임시"방법으로'clone '에 의해 생성 된 저수준 작업이 아니라'pthread' 스레드가 될 것으로 기대합니다. – Kaz

    답변

    0

    아마 그것이 작동하지 않는 이유를 알아 냈습니다.

    나는 errno이 쓰레드에 안전하다는 것을 읽었으며, pthread은 (g) libc에서 사용하는 스레드 로컬 변수를 생성했기 때문에 생각합니다.

    0

    와 스택하지만 아무 잘못 분석하는 고장을 시도 질문을 던지면 두 가지가 두드러집니다.

    1) ad-hoc 복제본에서 printf를 호출하려고합니다. 도중에 표준 라이브러리 쓰레기가있을 수 있습니다.

    2) 4k 스택 만 제공.

    printf(...)write(2, ...)으로 바꾸고 더 나은 동작을하는지 확인하십시오. 당신은 여전히 ​​당신의 손에 두통이 있지만 그것은 곧 당신의 아래에서 떨어지지 않을 것입니다.

    아니면 gdb

    exit() 종료 모든 스레드를보십시오. 어쩌면 다른 방법으로 나가야 할 수도 있습니다. 생성 된 스레드 함수에서 돌아 오는 것은 나쁜 생각인데, 이것은 메인 스레드의 스택을 처리하기 때문입니다.

    +0

    자세한 내용을 보려면 "EDIT 1"을 추가했습니다. 나는 또한 내 스레드에서'printf's'를 제거했지만 여전히 동일합니다. 하지만 4k 스택을 제공하지는 않습니다. 실제로 0x7fff = 32767B입니다. – Juju17ification

    관련 문제