我做了一个文档/视图程序,数据处理放在文档类中,需要和自定义的工作线程通信,请问是不是应该将文档类指针传给这个指针呢,是不是this?应该将线程函数声明成全局函数还是文档类的静态成员函数呢?请各位高手帮忙啊~

解决方案 »

  1.   

    可以定义一个全局的指针 g_pDocument
    在 CXView::OnCreate 之后 
    g_pDocument = GetDocument();
    线程函数声明成全局函数还是静态成员都没有关系,只是在逻辑上合理就好
      

  2.   

    To qrlvls:
          谢谢!请问为什么在view中获得文档指针呢,我是想在文档类中处理数据,将要处理的子任务交给子线程啊。还有一个问题想请教:在我的文档类的数据处理过程中,将不断有新的子任务产生,子任务主要有几类,我是将子任务线程函数做成消息队列可以不断接受任务处理任务,还是就做成一个单独的执行函数,在每次分配子任务时用AfxBeginThread开启一个线程呢
      

  3.   

    To qrlvls:
          谢谢!请问为什么在view中获得文档指针呢,我是想在文档类中处理数据,将要处理的子任务交给子线程啊。
    ---------------------------
    这样可以在适当的时机保证对象被初始化完成你后面的问题要根据具体的应用而定,可以再描述详细一些
      

  4.   

    To qrlvls:
           是这样的,程序总控制上需要每隔一定时间调用某算法,但是为了不影响界面不停的刷新,我打算把这些算法做成工作线程,问题就是:因为它们要不时地调用,我是做一个消息队列线程把调用视为给消息队列发消息呢,还是就把算法做成一个线程函数,不时地开启这个线程调用算法呢? 谢谢!!
      

  5.   

    线程函数的声明推荐使用微软的方法,一般也可以使用在文档类或者视图类中定义一个静态函数,两种方法如下:
    微软:在启动线程的文件头定义如下函数,
    UINT MyThreadProc( LPVOID pParam )
    {
        CMyObject* pObject = (CMyObject*)pParam;    if (pObject == NULL ||
            !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
        return 1;   // if pObject is not valid    // do something with 'pObject'    return 0;   // thread completed successfully
    }启动线程时,将你的指针传给LPVOID pParam,如下所示:
    pNewObject = new CMyObject;
    AfxBeginThread(MyThreadProc, pNewObject);
    另外一种静态函数方法:
    static UINT CYourClass::MyThreadProc(LPVOID pParam)
    {
        COtherClass *pClass = (COtherClass *)pParam;
        // use pClass do your something!
        return someUINT;
    }启动线程同上。// 不推荐使用定时器方式,因为当你的数据处理非常耗时的时候,使用定时器方式仍然会使得你的程序“假死”关于线程的问题有如下描述:
    创建辅助线程是一个相对较为简单的任务。只需两步即可以使线程运行:实现控制函数和启动线程。不必从 CWinThread 派生类。如果需要特殊版本的 CWinThread,也可以从 CWinThread 派生类,但是大多数简单的辅助线程都不需要。无需修改即可使用 CWinThread。启动线程
    AfxBeginThread 有两个重载版本:一个用于用户界面线程,一个用于辅助线程。若要开始执行辅助线程,请调用 AfxBeginThread 提供下列信息: 控制函数的地址。 
    要传递到控制函数的参数。 
    (可选)所需的线程优先级。默认值为正常优先级。有关可用的优先级级别的更多信息,请参见 Platform SDK 中的 SetThreadPriority。 
    (可选)所需的线程堆栈大小。默认值与创建线程的堆栈大小相同。 
    (可选)CREATE_SUSPENDED,如果希望在挂起状态中创建线程。默认值为 0,即正常启动线程。 
    (可选)所需的安全属性。默认值与父线程具有相同的访问权。有关此安全信息格式的更多信息,请参见 Platform SDK 中的 SECURITY_ATTRIBUTES。 
    AfxBeginThread 为您创建和初始化 CWinThread 对象、启动该对象并返回其地址,以便以后引用。在整个过程中进行检查,确保假如创建过程的任何部分出现故障,所有对象都能被正确地解除分配。实现控制函数
    控制函数定义线程。输入此函数后线程开始,此函数退出时线程终止。此函数的原型应为:UINT MyControllingFunction( LPVOID pParam );
    参数是单个 32 位值。函数在此参数中接收的值是在创建线程对象时传递到构造函数的值。控制函数可以用其选择的任何方式解释此值。可以将其视为标量值,或指向包含多个参数的结构的指针,也可以忽略此值。如果参数引用结构,则既可以使用该结构将数据从调用方传递到线程,也可以用该结构将数据从线程传递回调用方。如果使用此类结构将数据传递回调用方,当结果准备好时,线程将需要修改调用方。有关从辅助线程向调用方进行通信的信息,请参见多线程编程:编程提示一文。函数终止后,应该返回指示终止原因的 UINT 值。一般情况下,此退出代码为 0 指示成功;若为其他值,则指示不同类型的错误。这只依赖于实现。某些线程可以维护对象的使用计数,并返回该对象的当前使用数。若要查看应用程序如何检索此值,请参见多线程编程:终止线程一文。对在使用 Microsoft 基础类库写入的多线程程序中可以进行的操作有一些限制。有关这些限制的说明以及使用线程的其他提示,请参见多线程编程:编程提示一文。控制函数示例
    此示例说明如何定义控制函数并从程序的其他部分使用此函数。UINT MyThreadProc( LPVOID pParam )
    {
        CMyObject* pObject = (CMyObject*)pParam;    if (pObject == NULL ||
            !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
        return 1;   // if pObject is not valid    // do something with 'pObject'    return 0;   // thread completed successfully
    }// inside a different function in the program
    .
    .
    .
    pNewObject = new CMyObject;
    AfxBeginThread(MyThreadProc, pNewObject);
    .
    .
    .