程序运行时,发生死锁后,主线程(ui)从菜单选折exit,5个work线程是如何结束的呢,哪位高手能详细阐述一下worker线程死锁后,主线程是如何结束程序的呢

解决方案 »

  1.   

    用Te r m i n a t e T h r e a d,或者 进程终止, 线程也终止了
      

  2.   

    TerminateThread中止线程
    进程结束的话,所有的线程也就中止了
      

  3.   

    那线程占用的资源没有被释放掉吧,数据就没有写到硬盘上吧。
    我想知道的是 主线程退出WinMain时,WORK线程没有正常结束就会被TerminateThread中止线程,进程结束我的理解没有错吧
      

  4.   

    TerminateThread,直接终止的线程。
      

  5.   

    TerminateProcess结束进程,进程结束,系统会释放改进程所使用的所有资源如果主线程没有调用TerminateThread结束work线程,或是调用TerminateProcess结束自己的,而是仅结束主线程的话,当前进程继续存在,直到所有work线程退出或被终止
      

  6.   

    /*
     * Mutex.c
     *
     * Sample code for "Multithreading Applications in Win32"
     * This sample is discussed in Chapter 4.
     *
     * Graphically demonstrates the problem of the
     * dining philosophers.
     *
     * This version uses mutexes with WaitForSingleObject(),
     * which can cause deadlock, and WaitForMultipleObjects(),
     * which always works properly.
     */#define WIN32_LEAN_AND_MEAN
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <time.h>
    #include "MtVerify.h"
    #include "dining.h"
    int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
    BOOL InitApplication(HINSTANCE);
    BOOL InitInstance(HINSTANCE, int);extern HWND    hWndMain; // Main Window Handle                             
    extern BOOL bWaitMultiple;
    extern BOOL bFastFood;#define P_DELAY bFastFood ? rand()/25 : ((rand()%5)+1)*1000int gDinerState[PHILOSOPHERS];
    int gChopstickState[PHILOSOPHERS];HANDLE gchopStick[PHILOSOPHERS]; // 1 chopstick between each philopher and his neighbor#undef PostMessage
    #define PostMessage SendMessageDWORD WINAPI PhilosopherThread(LPVOID pVoid)
    {
    HANDLE myChopsticks[2];
    int iPhilosopher = (int) pVoid;
    int iLeftChopstick = iPhilosopher;
    int iRightChopstick = iLeftChopstick + 1;
    DWORD result; if (iRightChopstick > PHILOSOPHERS-1)
    iRightChopstick = 0;    //Randomize the random number generator
    srand( (unsigned)time( NULL ) * (iPhilosopher + 1) ); // remember handles for my chopsticks
    myChopsticks[0] = gchopStick[iLeftChopstick];
    myChopsticks[1] = gchopStick[iRightChopstick]; gDinerState[iPhilosopher] = RESTING; //wants chopsticks    Sleep(P_DELAY); for(;;)
    {
    if (bWaitMultiple == FALSE)
    {
    // Wait until both of my chopsticks are available
    gDinerState[iPhilosopher] = WAITING; //wants chopsticks
                PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
    result = WaitForSingleObject(gchopStick[iLeftChopstick], INFINITE);
    MTVERIFY(result == WAIT_OBJECT_0);
    gChopstickState[iLeftChopstick] = iPhilosopher;
    Sleep(P_DELAY/4); gDinerState[iPhilosopher] = WAITING; //wants chopsticks
                PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
    result = WaitForSingleObject(gchopStick[iRightChopstick], INFINITE);
    MTVERIFY(result == WAIT_OBJECT_0);
    gChopstickState[iRightChopstick] = iPhilosopher;
    }
    else
    {
    // Wait until both of my chopsticks are available
    gDinerState[iPhilosopher] = WAITING; //wants chopsticks
    PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
    result = WaitForMultipleObjects(2, myChopsticks, TRUE, INFINITE);
    MTVERIFY(result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + 2);
    gChopstickState[iLeftChopstick] = iPhilosopher;
    gChopstickState[iRightChopstick] = iPhilosopher;
    } // Philosopher can now eat a grain of rice
    gDinerState[iPhilosopher] = EATING; //philosopher is eating
    PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
            Sleep(P_DELAY); // Put down chopsticks
    gDinerState[iPhilosopher] = RESTING; //philosopher is resting
    gChopstickState[iRightChopstick] = UNUSED;
    gChopstickState[iLeftChopstick] = UNUSED;
    PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
    MTVERIFY( ReleaseMutex(gchopStick[iLeftChopstick]) );
    MTVERIFY( ReleaseMutex(gchopStick[iRightChopstick]) ); // Philosopher can now meditate
            Sleep(P_DELAY); } // end for return 0;
    }int Diner(void)
    {
    HANDLE hThread[PHILOSOPHERS];
    DWORD dwThreadId;
    int i; for (i=0; i < PHILOSOPHERS; i++)
    {
    //Initialize the chopsitcks to unused
    gChopstickState[i] = UNUSED;
    // initialize the diner state table
    gDinerState[i] = 0;
    // The Philosophers prepare to eat
    gchopStick[i] = CreateMutex(NULL, FALSE, NULL);
    MTVERIFY(gchopStick[i] != NULL);
    } for (i = 0; i < PHILOSOPHERS; i++)
    MTVERIFY( hThread[i] = CreateThread(NULL, 0, PhilosopherThread, (LPVOID) i, 0, &dwThreadId )); return 0;
    }
      

  7.   

    /*
     * Dining.c
     *
     * Sample code for "Multithreading Applications in Win32"
     * This sample is discussed in Chapter 4.
     *
     * Graphically demonstrates the problem of the
     * dining philosophers.
     */#define WIN32_LEAN_AND_MEAN
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <windowsx.h>
    #include <string.h>
    #include <math.h>
    #include "dining.h"HINSTANCE  hInst; // Application Instance Handle
    HWND    hWndMain;        // Main Window Handle                             
    HBITMAP hbmpOffscreen;LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    void RenderOffscreen(HDC hDestDC);BOOL bWaitMultiple;
    BOOL bFastFood;extern int gDinerState[];
    extern int gChopstickState[];
    extern HANDLE gchopStick[PHILOSOPHERS]; // 1 chopstick between each philopher and his neighbor/********************************************************************/
    /* ROUTINE: WndProc */
    /* */
    /* PURPOSE: Processes messages */
    /********************************************************************/LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
    WPARAM wParam, LPARAM lParam)
    {
    PAINTSTRUCT ps;
    HDC hdc; switch (message) 
    {
    case WM_COMMAND:
    switch (wParam) 
    {
    case CM_EXIT:
    PostMessage(hWndMain, WM_CLOSE, 0, 0L);
    break;  

    break; case WM_FORCE_REPAINT:
    {
    MSG msg; InvalidateRect(hWndMain, NULL, TRUE);
    while (PeekMessage(&msg, hWndMain, WM_FORCE_REPAINT,WM_FORCE_REPAINT,TRUE))
    ;
    }
    break; case WM_PAINT:

    hdc = BeginPaint(hWndMain, &ps); RenderOffscreen(hdc);

    EndPaint(hWndMain, &ps);
    break; case WM_CLOSE:
    return DefWindowProc(hWndMain, message, wParam, lParam); case WM_DESTROY:
    PostQuitMessage(0);
    break; default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return (0);
    }BOOL CreateOffscreen()
    {
    HWND hwndScreen = GetDesktopWindow();
    HDC hdc = GetDC(hwndScreen); int nWidth = GetSystemMetrics( SM_CXSCREEN );
    int nHeight = GetSystemMetrics( SM_CYSCREEN ); hbmpOffscreen = CreateCompatibleBitmap( hdc, nWidth, nHeight ); ReleaseDC(hwndScreen, hdc); if ( !hbmpOffscreen )
    return FALSE;
    else
    return TRUE;
    }void RenderOffscreen(HDC hDestDC)
    {
    HDC hdc = hDestDC; // CreateCompatibleDC(hWndMain);
    int err=GetLastError();
    HBITMAP hOldBitmap = SelectObject(hdc, hbmpOffscreen);
    RECT rect;
    HPEN hPen;
    double dx, dy, px, py,  AngRad, dDeltaAng;
    int pos, p1;
    long CenterX, CenterY; hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, 0L)); GetClientRect(hWndMain, &rect); /* Draw the table */
    CenterX = (rect.right - rect.left)/2;
    CenterY = (rect.bottom - rect.top)/2;
    Ellipse(hdc, CenterX - 100, CenterY - 100, CenterX + 100, CenterY + 100); /* Draw the chopsticks */
    dDeltaAng = 360 / PHILOSOPHERS;
    for (pos = 0; pos < PHILOSOPHERS; pos++) //FIXIT
    {
    /* Draw the chopsticks */
    AngRad = (pos * dDeltaAng)/57.29577951;
    dx = CenterX + (sin(AngRad)*60);
    dy = CenterY - (cos(AngRad)*60);
    MoveToEx(hdc, (int)dx, (int)dy, NULL);
    dx = CenterX + (sin(AngRad)*85);
    dy = CenterY - (cos(AngRad)*85);
    LineTo(hdc, (int)dx, (int)dy); //Draw the plate
    AngRad = ((pos * dDeltaAng+dDeltaAng / 2))/57.29577951;
    dx = CenterX + (sin(AngRad) * 72);
    dy = CenterY - (cos(AngRad) * 72);
    Ellipse(hdc, (int)dx-12, (int)dy-12, (int)dx+12, (int)dy+12);
    } /* delete the black pen */
    DeleteObject(SelectObject(hdc, hPen)); /* Draw the philosophers */
    for(pos = 0; pos < PHILOSOPHERS; pos++)
    {
    /* select a pen for each philosopher */
    switch (gDinerState[pos])
    {
    case RESTING:
    hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 255, 0)));
    break; case WAITING:
    case EATING:
    hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
    break; default:
    hPen = SelectObject(hdc, CreatePen(PS_SOLID, 3, 0L));
    } AngRad = ((pos * dDeltaAng) + dDeltaAng / 2)/57.29577951;
    px = CenterX + (sin(AngRad)*150);
    py = CenterY - (cos(AngRad)*150); /* Draw the Philosopher */
    Ellipse(hdc, (int)px-25, (int)py-25, (int)px+25, (int)py+25); //Draw the left arm
    if (gChopstickState[pos] == pos)
    {
    MoveToEx(hdc, (int)px, (int)py, NULL);
    AngRad = (pos * dDeltaAng)/57.29577951;
    dx = CenterX + (sin(AngRad)*85);
    dy = CenterY - (cos(AngRad)*85);
    LineTo(hdc, (int)dx, (int)dy);
    } //Draw the right arm
    p1 = pos + 1;
    if (p1 == PHILOSOPHERS)
    p1 = 0;
    if (gChopstickState[p1] == pos)
    {
    MoveToEx(hdc, (int)px, (int)py, NULL);
    AngRad = (p1 * dDeltaAng)/57.29577951;
    dx = CenterX + (sin(AngRad)*85);
    dy = CenterY - (cos(AngRad)*85);
    LineTo(hdc, (int)dx, (int)dy);
    } /* Delete the pen */
    DeleteObject(SelectObject(hdc, hPen));
    } //for pos BitBlt( hDestDC,
    rect.left,
    rect.top,
    rect.right - rect.left,
    rect.bottom-rect.top,
    hdc,
    rect.left,
    rect.top,
    SRCCOPY
    );
    GetLastError(); SelectObject(hdc, hOldBitmap);// DeleteDC(hWndMain, hdc);
    }/********************************************************************/
    /* ROUTINE: InitApplication */
    /* */
    /* PURPOSE: Initialize the application */
    /********************************************************************/BOOL InitApplication(HINSTANCE hInstance)
    {
    WNDCLASS  wc; wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wc.lpszMenuName =  "din";
    wc.lpszClassName = "dinWClass"; RegisterClass(&wc); return TRUE;
    }
    /********************************************************************/
    /* ROUTINE:  InitInstance */
    /* */
    /* PURPOSE:  Saves instance handle and creates main window */
    /********************************************************************/BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
    int ret; hInst = hInstance; hWndMain = CreateWindow(
    "dinWClass",
    "Dining Philosopher",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    450,
    450,
    NULL, NULL, hInstance, NULL ); if (!hWndMain)
    return FALSE; ShowWindow(hWndMain, nCmdShow);
    UpdateWindow(hWndMain); if (!CreateOffscreen())
    PostQuitMessage(1); ret = MessageBox(hWndMain, "Do you want to use WaitForMultipleObjects()?\n\n"
    "If you select Yes, then the application will run all day.\n"
    "If you select No, then the application can deadlock.\n",
    "Wait Mode", MB_YESNO);
    if (ret == IDYES)
    bWaitMultiple = TRUE;
    else
    {
    bWaitMultiple = FALSE; ret = MessageBox(hWndMain, "Do you want fast philosophers?\n\n"
    "If you select Yes, then it will deadlock much faster.\n",
    "Wait Mode", MB_YESNO);
    if (ret == IDYES)
    bFastFood = TRUE;
    else
    bFastFood = FALSE;
    } // Start the threads
    Diner(); return TRUE;
    }/********************************************************************/
    /* FUNCTION: WinMain */
    /* */
    /* PURPOSE: Calls initialization function, processes message loop */
    /********************************************************************/int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow)
    {
    MSG msg;
    int i; if (!hPrevInstance)
    if (!InitApplication(hInstance))
        return (FALSE); if (!InitInstance(hInstance, nCmdShow))
       return (FALSE); while (GetMessage(&msg, NULL, 0, 0)) 
    {
    TranslateMessage(&msg);
      DispatchMessage(&msg); 
    }
    // Clear the table
    for (i = 0; i < PHILOSOPHERS; i++)
    CloseHandle(gchopStick[i]);
      
    return (msg.wParam);
    }
      

  8.   

    /********************************************************/
    /* Dining.h - Application Prototypes & Definitions       */
    /********************************************************/// Dining Philosophers Globals
    #define UNUSED -1
    #define RESTING         0
    #define WAITING         1
    #define EATING          2#define PHILOSOPHERS    5       // Number of philosophers#define WM_FORCE_REPAINT WM_APP+10
    #define CM_EXIT         1000

    int Diner(void);