读了田海立老师的两篇文章 winCE系统的同步机制 关于 Windows CE 系统中同步机制的思考,受益匪浅。于是写代码验证了一下,
测试环境winCE6.0
主函数所在的文件testthread.cpp
// testthread.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "threadtest.h"
//#include "pwinuser.h"
HANDLE threadhdary[MAXTDLEN];
DWORD threadidary[MAXTDLEN];
int threadparam[MAXTDLEN];
bool finishflag[MAXTDLEN];
unsigned int threadcnt;
//CRITICAL_SECTION g_cs;
int _tmain(int argc, _TCHAR* argv[])
{
cout<<"like it\n be no 1"<<endl;
int cmdvar=0;
//cin>>cmdvar;
testfile.open("\\windows\\outputfile.txt",ios::out);
InitializeCriticalSection(&g_cs);
for (int i=0;i<3;i++)
{
threadparam[threadcnt]=threadcnt+1;
threadhdary[threadcnt]=CreateThread(
NULL, //LPSECURITY_ATTRIBUTES lpsa,The security attributes for the new thread.
NULL, //DWORD dwStackSize,The stack size for the new thread.
threadProc, //The thread procedure of the new thread.
&threadparam[threadcnt], //void* pvParam,The parameter to be passed to the thread procedure.
0, //0:立即执行,CREATE_SUSPENDED;需要被唤醒
&threadidary[threadcnt]); //[out] Address of the DWORD variable that, on success, receives the thread ID of the newly created thread.
if (threadcnt==2)
{
CeSetThreadPriority(threadhdary[threadcnt],180);
//CeSetThreadQuantum(threadhdary+threadcnt,10);
}
else
{
CeSetThreadPriority(threadhdary[threadcnt],181);
//CeSetThreadQuantum(threadhdary+threadcnt,10);
}
if (NULL!=threadhdary[threadcnt])
{
threadcnt++;
}
}
// bool rtnflag=false;
// threadparam[threadcnt]=threadcnt+1;
// threadhdary[threadcnt]=CreateThread(
// NULL, //LPSECURITY_ATTRIBUTES lpsa,The security attributes for the new thread.
// NULL, //DWORD dwStackSize,The stack size for the new thread.
// thread1Proc, //The thread procedure of the new thread.
// threadparam+threadcnt, //void* pvParam,The parameter to be passed to the thread procedure.
// CREATE_SUSPENDED, //0:立即执行,CREATE_SUSPENDED;需要被唤醒
// &threadidary[threadcnt]); //[out] Address of the DWORD variable that, on success, receives the thread ID of the newly created thread.
// rtnflag=CeSetThreadPriority(threadhdary[threadcnt],120);
// //rtnflag=CeSetThreadPriority(threadhdary+threadcnt,255);//最初写错了
//
// DWORD tempdw=GetLastError();
// if (!rtnflag)
// {
// int a=0xff;
// }
// threadcnt++;
// threadparam[threadcnt]=threadcnt+1;
// threadhdary[threadcnt]=CreateThread(
// NULL, //LPSECURITY_ATTRIBUTES lpsa,The security attributes for the new thread.
// NULL, //DWORD dwStackSize,The stack size for the new thread.
// thread2Proc, //The thread procedure of the new thread.
// threadparam+threadcnt, //void* pvParam,The parameter to be passed to the thread procedure.
// 0, //0:立即执行,CREATE_SUSPENDED;需要被唤醒
// &threadidary[threadcnt]); //[out] Address of the DWORD variable that, on success, receives the thread ID of the newly created thread.
// rtnflag=CeSetThreadPriority(threadhdary[threadcnt],120);
// if (!rtnflag)
// {
// int a=0xff;
// }
//
// threadcnt++;
// threadparam[threadcnt]=threadcnt+1;
// threadhdary[threadcnt]=CreateThread(
// NULL, //LPSECURITY_ATTRIBUTES lpsa,The security attributes for the new thread.
// NULL, //DWORD dwStackSize,The stack size for the new thread.
// thread3Proc, //The thread procedure of the new thread.
// threadparam+threadcnt, //void* pvParam,The parameter to be passed to the thread procedure.
// 0, //0:立即执行,CREATE_SUSPENDED;需要被唤醒
// &threadidary[threadcnt]); //[out] Address of the DWORD variable that, on success, receives the thread ID of the newly created thread.
// rtnflag=CeSetThreadPriority(threadhdary[threadcnt],60);
// if (!rtnflag)
// {
// int a=0xff;
// }
while (true)
{
//cin>>cmdvar;
if (cmdvar)
{
break;
}
Sleep(100);
}
for (int i=0;i<MAXTDLEN;i++)
{
threadparam[i]=0;
}
// Sleep(1000);
bool threadquitflag=false;
do
{
int i=0;
threadquitflag=true;
while (threadquitflag&&(i<3))
{
threadquitflag=threadquitflag&&finishflag[i++];
}
Sleep(100);
} while (!threadquitflag);
for (int i=0;i<MAXTDLEN;i++)
{
//TerminateThread(threadhdary[i],0);//临界区内可能导致临界区不被释放
CloseHandle(threadhdary[i]);
}
testfile.close();
DeleteCriticalSection(&g_cs);
//thread1Proc();
return 0;
}
线程函数体定义放在了另外一个cpp里
//CRITICAL_SECTION g_cs;
#include "stdafx.h"
#include "threadtest.h"
CRITICAL_SECTION g_cs;
fstream testfile;
DWORD threadProc(LPVOID lpParm)//测试移入.h
{
int exterparam=*(int *)lpParm;
int threadparam=exterparam-1;//相对量
while(exterparam)
{
EnterCriticalSection(&g_cs);
exterparam=*(int *)lpParm;
//cout<<"thread "<<cnt<<" is running"<<endl;
testfile<<"thread "<<threadparam+1<<" is running"<<endl;
Sleep(1);//注意必须有阻塞或者有段时间不参与时间片竞争
LeaveCriticalSection(&g_cs);
}
finishflag[threadparam]=true;
return 1;
}
DWORD thread1Proc(LPVOID lpParm)//测试移入.h
{
int cnt=*(int *)lpParm;
while(cnt)
{
cout<<"thread 1 try to enter"<<endl;
EnterCriticalSection(&g_cs);
cnt=*(int *)lpParm;
//cout<<"thread "<<cnt<<" is running"<<endl;
testfile<<"thread 1 is running"<<endl;
LeaveCriticalSection(&g_cs);
cout<<"thread 1 leave"<<endl;
//Sleep(5);
}
return 1;
}
DWORD thread2Proc(LPVOID lpParm)//测试移入.h
{
int cnt=*(int *)lpParm;
while(cnt)
{
cout<<"thread 2 try to enter"<<endl;
EnterCriticalSection(&g_cs);
cnt=*(int *)lpParm;
//cout<<"thread "<<cnt<<" is running"<<endl;
testfile<<"thread 2 is running"<<endl;
LeaveCriticalSection(&g_cs);
cout<<"thread 2 leave"<<endl;
//Sleep(5);
}
return 1;
}
DWORD thread3Proc(LPVOID lpParm)//测试移入.h
{
int cnt=*(int *)lpParm;
while(cnt)
{
cout<<"thread 3 try to enter"<<endl;
EnterCriticalSection(&g_cs);
cnt=*(int *)lpParm;
//cout<<"thread "<<cnt<<" is running"<<endl;
testfile<<"thread 3 is running"<<endl;
LeaveCriticalSection(&g_cs);
cout<<"thread 3 leave"<<endl;
//Sleep(5);
}
return 1;
}
还有一个头文件
#ifndef THREAD_TEST_H
#define THREAD_TEST_H
#include "iostream"
#include "winbase.h"
#include "fstream"
using namespace std;
using namespace std;
#define MAXTDLEN 20
DWORD threadProc(LPVOID);
DWORD thread1Proc(LPVOID);
DWORD thread2Proc(LPVOID);
DWORD thread3Proc(LPVOID);
extern CRITICAL_SECTION g_cs;
extern fstream testfile;
extern bool finishflag[MAXTDLEN];
// DWORD thread1Proc(LPVOID lpParm)//测试移入.h
// {
// while(true)
// {
// EnterCriticalSection(&g_cs);
// int cnt=*(int *)lpParm;
// cout<<"thread "<<cnt<<" is running"<<endl;
// LeaveCriticalSection(&g_cs);
// //Sleep(1000);
//
// }
// }
#endif
注意一点 threadProc(LPVOID lpParm)里不能总是占用时间片,需要阻塞或人为sleep,winCE不负责抢占调度,会死机。
还有一点,winCE6.0支持的最大进程数增加了,不止32个。