win32多线程程序设计附书源码的哲学家进餐问题

图灵转世 2004-11-21 01:45:20
程序运行时,发生死锁后,主线程(ui)从菜单选折exit,5个work线程是如何结束的呢,哪位高手能详细阐述一下worker线程死锁后,主线程是如何结束程序的呢
...全文
212 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
图灵转世 2004-11-22
  • 打赏
  • 举报
回复
那线程占用的资源没有被释放掉吧,数据就没有写到硬盘上吧。
我想知道的是 主线程退出WinMain时,WORK线程没有正常结束就会被TerminateThread中止线程,进程结束

我的理解没有错吧
DentistryDoctor 2004-11-22
  • 打赏
  • 举报
回复
TerminateThread,直接终止的线程。
图灵转世 2004-11-22
  • 打赏
  • 举报
回复
/********************************************************/
/* 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);


图灵转世 2004-11-22
  • 打赏
  • 举报
回复
/*
* 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);
}
图灵转世 2004-11-22
  • 打赏
  • 举报
回复
/*
* 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)*1000

int gDinerState[PHILOSOPHERS];
int gChopstickState[PHILOSOPHERS];

HANDLE gchopStick[PHILOSOPHERS]; // 1 chopstick between each philopher and his neighbor

#undef PostMessage
#define PostMessage SendMessage

DWORD 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;
}
tabris17 2004-11-22
  • 打赏
  • 举报
回复
TerminateProcess结束进程,进程结束,系统会释放改进程所使用的所有资源

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



oyljerry 2004-11-21
  • 打赏
  • 举报
回复
TerminateThread中止线程
进程结束的话,所有的线程也就中止了
property1 2004-11-21
  • 打赏
  • 举报
回复
用Te r m i n a t e T h r e a d,

或者 进程终止, 线程也终止了
linxy2002 2004-11-21
  • 打赏
  • 举报
回复
学习

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧