程序运行时,发生死锁后,主线程(ui)从菜单选折exit,5个work线程是如何结束的呢,哪位高手能详细阐述一下worker线程死锁后,主线程是如何结束程序的呢
解决方案 »
- 求教SNMP++ 接收inform消息的问题?
- Visual C++网络通信编程实用案例精选(第二版 这书上面的代码是MFC写的吗?还是什么?
- 谁可以给些操作硬盘的例子,急
- 在VC下写的程序如何才能具有XP的风格?
- 如何画矩形和椭圆,但不填充区域?
- 一个程序员的户口问题,救救我吧,UP 者有分!!
- 高分求购会计中凭证录入控件,有谁做过给点提示也行1
- 如何将一个图片做为背景画面,在上面可加一些空件呢!!!!!急
- ====>请问:你们用VC++第一次编程的时候是怎样下手的?<====
- 客户端在一个线程中做connect( ),如何让程序切断connecting...??
- 同一台计算机上,同一个组播组绑定多个套接字的问题
- 如何编写应用程序共享
进程结束的话,所有的线程也就中止了
我想知道的是 主线程退出WinMain时,WORK线程没有正常结束就会被TerminateThread中止线程,进程结束我的理解没有错吧
* 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;
}
* 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);
}
/* 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);