要求:写一个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部分的代码,多谢了,多余多线程不是很熟悉 :)頂帖有分,十万火急!!!

解决方案 »

  1.   

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★上面的问题基本上已经解决了,但是为了把200送出,想请大家帮忙解决:如果处理在双CPU情况下,同样使用多线程中,如何互斥访问临界资源(比如这里的MyList)?★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
      

  2.   

    你的意思是可能有多个线程操作MyList类,不是在MyList类中实现多个线程?
    如果是这样,就应该把MyList类做成线程安全类.也就是在所有涉及到数据成员操作的成员函数中,进行同步.我认为,用信号量进行同步比较合适.
    另外提一点意见:所有的字符串放在MyList类中,并有增删操作,而你仅有char* Strings[MAX_NUMS];,这显然增加自己的编程难度.除非你是在c++编程,不能用mfc.否则,建议用基于CString的链表或者数组(mfc中有现成的).这样你编程时只需考虑同步问题,而不需太多精力考虑操作实现问题.
      

  3.   

    一时糊涂,就准备自己写类了,事实上的确如horin所言,直接利用CStringList就可以了,利用 OpenMutex,CreateMutex 可以解决临界资源的问题。当出现两个CPU的情况下,该如何解决呢?确切地讲,怎么写有关CPU在此问题上地代码?
      

  4.   

    在单CPU下本问题可以如下解决:int           iCounter=0;
    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情况下,如何解决本问题? 谢谢!!!
      

  5.   

    --------------------------------------------------------------
    通过调用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);
      

  6.   

    同意hwonzor(闲人),详细看参考<Windows核心编程>,实现真正的多线程.
      

  7.   

    to 闲人:
    OpenMutex,WaitForSingleObject 等是不是在多CUP下也是适用的?也就是说,即使在多CUP下,如果我用OpenMutex,WaitForSingleObject来对临界资源(CStringList) 的增删进行信号量控制,也是起作用的?因为我的目的是,在多CPU下,多线程对于同一资源(CStringList)进行增删的时候,不会发生程序崩溃(如果同时有两个线程去删除同一个地址,就会崩溃)
      

  8.   

    在多cpu下同步对象没有问题,Mutex当然也可以
    但看你的要求,俺觉得使用关键区更合适一些
    InitializeCriticalSection
    EnterCriticalSection 
    LeaveCriticalSection 
    DeleteCriticalSection在你的类中可以包含一个关键区对象作为成员变量
    构造函数或你自己的初始化函数中Initialize..
    析构的时候或你自己的清除类对象的函数中Delete...在你的某些敏感函数中开始的部分,Enter...
    函数结束的时候Leave(非常重要)
      

  9.   

    操作系统提供的同步对象在多cpu下当然是没有问题的,Mutex当然也可以但看你的需求,俺觉得使用关键区可能更容易理解
    InitializeCriticalSection
    EnterCriticalSection
    LeaveCriticalSection 
    DeleteCriticalSection尽管你可以直接使用MFC提供的容器类,但还是建议你用自己的类把MFC的类封装为一个线
    程安全的类,不要在线程代码中去直接实现线程同步之类的操作,
    那样麻烦,代码不容易理解.而是,让你的类自身就有线程安全的特性.简单地说,(以使用关键区为例,当然,Mutex也可以,但对这类情况,俺习惯用关键区)在你的类的构造函数或你自己定义的初始化函数中,Initialize...
    在你的类的析构函数或自己定义的清理函数中,Delete...在你的类的关键函数处,如增加,删除,取得大小等的函数的开头
    Enter...
    在函数执行完,返回前,Leave...这样,保证,任何线程在访问你的类的代码的时候,都经过关键区的检查,如果你的类对象已经在
    关键区了,那么新的线程必须等待其退出.这样避免了线程访问上的冲突.
      

  10.   

    kao,第一次写的没有发成功,再发竟然都出来了
      

  11.   

    zzyx(菜农)兄:
       不好意思,邀请你来,我居然急急结帐了,算我欠你分,下次还上,呵呵,谢谢了。