要求:写一个MyList类,可以增加,删除字符串。所有的字符串放在MyList类中,要求多线程实现。因为我们知道,如果一个线程中对Strings[index] 进行删除,而另一个进程去访问Strings[index];肯定会发生程序崩溃。初步设计类为:#define MAX_NUMS 100
class MyList
{
private:
int StringNums;
char* Strings[MAX_NUMS];public:
MyList();
~MyList();
int GetStringNums();
char* GetString(int index);
BOOL ResetString(int index,char* NewString);
BOOL AddString(char* NewString);
BOOL DeleteString(int index);
};希望大家在引入多线程操作的时候,帮我写一下AddString部分的代码,多谢了,多余多线程不是很熟悉 :)頂帖有分,十万火急!!!
class MyList
{
private:
int StringNums;
char* Strings[MAX_NUMS];public:
MyList();
~MyList();
int GetStringNums();
char* GetString(int index);
BOOL ResetString(int index,char* NewString);
BOOL AddString(char* NewString);
BOOL DeleteString(int index);
};希望大家在引入多线程操作的时候,帮我写一下AddString部分的代码,多谢了,多余多线程不是很熟悉 :)頂帖有分,十万火急!!!
解决方案 »
- CTreeControl加入图标的时候可以改变大小么
- SOCKET代码问题
- 对话框添加背景图
- C++ 里有没有 StrToTime 函数封装好的,谢谢
- 是不是接口参数中有SAFEARRAY类型的,就不能使用类型库??
- MFC中OnPaint和OnDraw 的使用区别
- VC链接时提示“invalid library format; library ignored”,请问怎么解决?
- 如何保证一个线程和另一个线程的一部分同步?
- sql表中有一字段类型是smalldatetim类型,默认值是(getdate()),但是我在添加是text1中的值时,如果text是空的话,则,数据显示是1900-01-01,我想让他要么显不是null,要么显不是当前日期
- 请问如何全屏显示我开发的小程序窗口(VC++6.0)
- 关于关闭窗口的问题
- 知道CDialog的资源id,怎么样获得它的句柄啊
如果是这样,就应该把MyList类做成线程安全类.也就是在所有涉及到数据成员操作的成员函数中,进行同步.我认为,用信号量进行同步比较合适.
另外提一点意见:所有的字符串放在MyList类中,并有增删操作,而你仅有char* Strings[MAX_NUMS];,这显然增加自己的编程难度.除非你是在c++编程,不能用mfc.否则,建议用基于CString的链表或者数组(mfc中有现成的).这样你编程时只需考虑同步问题,而不需太多精力考虑操作实现问题.
CStringList* pMyStrList;
CString mutexName = "Handle with Strings"; DWORD ThreadFunction(void* pD)
{
int iID=(int)pD;
char buf[120];
HANDLE MyMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutexName);
for(int i=0;i<3;i++)
{
WaitForSingleObject(MyMutex,INFINITE);
int iCopy=iCounter;
Sleep(100);
iCounter=iCopy+1;
switch(iID)
{
case 1: // Thread 1 adds a string to the list
printf("Handle %d: Thread %d adds String\n",iCounter,iID);
sprintf(buf,"Handle %d: Thread %d adds String\n",iCounter,iID);
pMyStrList->AddTail(buf);
break;
case 2: // Thread 2 deletes the last string of the list
printf("Handle %d: Thread %d deletes String\n",iCounter,iID);
pMyStrList->RemoveTail();
break;
}
ReleaseMutex(MyMutex);
}
CloseHandle(MyMutex);
return 0;
}int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
HANDLE MyMutex=NULL;
if( (MyMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutexName))==NULL)
{
MyMutex = CreateMutex(NULL,FALSE,mutexName);
}
pMyStrList = new CStringList;
HANDLE hThread[2];
CWinThread* pT1=AfxBeginThread((AFX_THREADPROC)ThreadFunction,(void*)1);
CWinThread* pT2=AfxBeginThread((AFX_THREADPROC)ThreadFunction,(void*)2);
hThread[0]=pT1->m_hThread;
hThread[1]=pT2->m_hThread;
WaitForMultipleObjects(2,hThread,TRUE,INFINITE);
CloseHandle(MyMutex);
delete pMyStrList;
return 0;
}★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★如果在双CPU情况下,如何解决本问题? 谢谢!!!
通过调用SetThreadAffinityMask,就能为各个线程设置亲缘性屏蔽:
DWORD_PTR SetThreadAffinityMask (
HANDLE hThread, // handle to thread
DWORD_PTR dwThreadAffinityMask // thread affinity mask
);
该函数中的 hThread 参数用于指明要限制哪个线程, dwThreadAffinityMask用于指明该线程
能够在哪个CPU上运行。dwThreadAffinityMask必须是进程的亲缘性屏蔽的相应子集。返回值
是线程的前一个亲缘性屏蔽。例如,可能有一个包含4个线程的进程,它们在拥有4个CPU的计算机上运行。如果这些线程中的一个线程正在执行非常重要的操作,而你想增加某个CPU始终可供它使用的可能性,为此你对其他3个线程进行了限制,使它们不能在CPU 0上运行,而只能在CPU 1、2和3上运行。因此,若要将3个线程限制到CPU 1、2和3上去运行,可以这样操作://线程0只能在cpu 0上运行
SetThreadAffinityMask(hThread0,0x00000001);
//线程1,2,3只能在cpu 1,2,3上运行
SetThreadAffinityMask(hThread1,0x0000000E);
SetThreadAffinityMask(hThread2,0x0000000E);
SetThreadAffinityMask(hThread3,0x0000000E);
OpenMutex,WaitForSingleObject 等是不是在多CUP下也是适用的?也就是说,即使在多CUP下,如果我用OpenMutex,WaitForSingleObject来对临界资源(CStringList) 的增删进行信号量控制,也是起作用的?因为我的目的是,在多CPU下,多线程对于同一资源(CStringList)进行增删的时候,不会发生程序崩溃(如果同时有两个线程去删除同一个地址,就会崩溃)
但看你的要求,俺觉得使用关键区更合适一些
InitializeCriticalSection
EnterCriticalSection
LeaveCriticalSection
DeleteCriticalSection在你的类中可以包含一个关键区对象作为成员变量
构造函数或你自己的初始化函数中Initialize..
析构的时候或你自己的清除类对象的函数中Delete...在你的某些敏感函数中开始的部分,Enter...
函数结束的时候Leave(非常重要)
InitializeCriticalSection
EnterCriticalSection
LeaveCriticalSection
DeleteCriticalSection尽管你可以直接使用MFC提供的容器类,但还是建议你用自己的类把MFC的类封装为一个线
程安全的类,不要在线程代码中去直接实现线程同步之类的操作,
那样麻烦,代码不容易理解.而是,让你的类自身就有线程安全的特性.简单地说,(以使用关键区为例,当然,Mutex也可以,但对这类情况,俺习惯用关键区)在你的类的构造函数或你自己定义的初始化函数中,Initialize...
在你的类的析构函数或自己定义的清理函数中,Delete...在你的类的关键函数处,如增加,删除,取得大小等的函数的开头
Enter...
在函数执行完,返回前,Leave...这样,保证,任何线程在访问你的类的代码的时候,都经过关键区的检查,如果你的类对象已经在
关键区了,那么新的线程必须等待其退出.这样避免了线程访问上的冲突.
不好意思,邀请你来,我居然急急结帐了,算我欠你分,下次还上,呵呵,谢谢了。