2016-12-20 2 views
-1

이것은 스레드를 다루는 처음입니다.WIN32 스레드 프로그램 문제

GetCurrentThreadId() 함수없이 프로그램을 실행하면 문제없이 실행됩니다.

코드 행을 추가해도 실행되지만 끝까지 도달하면 충돌합니다. 왜 이런거야?

#include <Windows.h> 
#include <stdio.h> 
#include <conio.h> 


static int tix[500]; 
static int done = 0; 
HANDLE ghSemaphore; 

DWORD WINAPI ThreadFunction(); 

int main(void) 
{ 
    DWORD threadID1, threadID2, threadID3, threadID4; 
    HANDLE hThread1, hThread2, hThread3, hThread4; 

    for (int i = 0; i < 500; i++) //initialize array 
    { 
     tix[i] = 0; 
    } 

    ghSemaphore = CreateSemaphore(NULL, 1, 10, NULL); 

    hThread1 = CreateThread(NULL, 0, ThreadFunction, NULL, 0, &threadID1); 
    hThread2 = CreateThread(NULL, 0, ThreadFunction, NULL, 0, &threadID2); 
    hThread3 = CreateThread(NULL, 0, ThreadFunction, NULL, 0, &threadID3); 
    hThread4 = CreateThread(NULL, 0, ThreadFunction, NULL, 0, &threadID4); 

    //printf("The thread ID: %d.\n", threadID1); 
    //printf("The thread ID: %d.\n", threadID2); 
    //printf("The thread ID: %d.\n", threadID3); 
    //printf("The thread ID: %d.\n", threadID4); 

    if (done = 1) 
    { 
     CloseHandle(hThread1); 
     CloseHandle(hThread2); 
     CloseHandle(hThread3); 
     CloseHandle(hThread4); 
    } 

    for (int j = 0; j < 500; j++) 
    { 
     if (tix[j] = 0) 
     { 
      printf("not sold"); 
     } 
     else if (tix[j] = 1) 
     { 
      printf("sold"); 
     } 
    } 

    return 0; 
} 

DWORD WINAPI ThreadFunction() 
{ 
    WaitForSingleObject(ghSemaphore, 0); 

    printf("current thread running : %d\n", GetCurrentThreadId()); 

    int i = 0; 
    if (done != 0) // if loop to test wether or not the array is full 
    { 
     while (tix[i] = 1) //traverse the array to find a open spot 
     { 
      i++; 
     } 
     tix[i] = 1; 

    } 
    if (i == 499) //if i is 499, set test variable to 1 
    { 
     done = 1; 
     return 0; 
    } 

    ReleaseSemaphore(ghSemaphore, 1, NULL); 
} 
+0

충돌 할 때 나타나는 오류 메시지는 무엇입니까? – jadhachem

+8

스레드 함수의 서명이 올바르지 않으므로 스택이 손상되었을 수 있습니다. 컴파일러 경고를 무시하지 마십시오. 또한'if (done = 1)'과'if (tix [j] = 1)'은 항상 참입니다. 멀티 스레딩을 시도하기 전에 기본 C를 마스터하는 것이 좋습니다. –

+0

코드가 스레드 핸들을 닫지 않습니다. 함수가 끝나면 WaitForMultipleObjects를 호출하고 핸들을 닫기 전에 모든 스레드가 실행되었는지 확인해야합니다. 말할 필요도없이,'done' 변수는 멀티 스레드 프로그램에서 난센스입니다. – Lundin

답변

0

스레드 기능에 잘못된 서명이 있습니다. 스레드는 하나의 PVOID 컨텍스트 인수를 취합니다

DWORD WINAPI ThreadProc(
    _In_ LPVOID lpParameter 
); 

귀하의 스레드가 세마포어를 해제하지 않고 종료 할 수있다. 또한 값을 스레드 값보다 크고 WaitForSingleObject 결과를 확인하지 않은 값으로 초기화 했으므로 동기화가 제공되지 않고 여러 스레드가 일관성없는 방식으로 공유 버퍼를 수정합니다. 심지어 악화 - 이전에 종료 한 프로그램 주 스레드가 멈추지 않는 것이 무엇이든 ThreadFunction입니다.

스레드 함수 끝에 return 문이 없으므로 이것은 정의되지 않은 동작입니다. 사실 여러분의 코드가 컴파일되는 것은 놀라운 일입니다. 멀티 스레딩에 대한이 전체 접근법은 잘못되어 처음부터 다시 만들어야합니다.

+2

이것은 아주 오랫동안 사실이 아니 었습니다. 이 경우 윈도우 스레드 풀이 작동하지 않을 수 있습니다. 대답의 후반부는 좋지만. –

+0

beginthread에 대한 귀하의 의견은 20 세와 같습니다. IIRC 이것은 Windows API가 아닌 Visual Studio 컴파일러의 버그 때문이었습니다. – Lundin

+0

음. MSDN에는 여전히이 권장 사항이 있습니다. 누구와 내가 모순 되는가?) – Ari0nhh