使用 MFC 清除 ONC RPC SVC_RUN() 退出

Posted

技术标签:

【中文标题】使用 MFC 清除 ONC RPC SVC_RUN() 退出【英文标题】:Clean Exit of ONC RPC SVC_RUN() with MFC 【发布时间】:2011-05-26 15:52:18 【问题描述】:

我对多线程代码很陌生,所以我希望有人可以帮助我解决我遇到的问题。

我有一个由 ONC/RPC 服务器和其他东西组成的多部分程序(“东西”与我的问题并不真正相关,但它必须在服务器程序中)。因为 svc_run() 永远不会返回,所以我想我会把它放在它自己的线程中,在程序结束时我会简单地终止线程并继续生活。

但是,我的程序现在已经扩展,我想干净、安全地退出或关闭 ONC/RPC 服务器,而不是终止线程。但是,我无法弄清楚如何安全地从 svc_run() 返回。有人能帮忙吗?

我发现其他几个人有同样的问题,但似乎没有人回应他们。我尝试简单地将 svc_run() 移动到与我的 server_process() 函数相同的文件中,但 fd_set 的结构没有正确填充(全部为 0),并且该函数失败。

svc_run() 定义在使用以下代码创建的 dll 中:http://sourceforge.net/projects/oncrpc-windows/

我正在提供我的代码的相关元素。另请注意,svc_exit() 似乎不是我当前使用的 onc/rpc 系统的一部分。

抱歉,问题太长了, 谢谢,

莱克斯

这是我的代码:

 //Code in Initialization of MFC Dialog
myThread = AfxBeginThread(startServing,NULL,THREAD_PRIORITY_NORMAL,0,0,NULL);

 // Thread that starts the server

 UINT __cdecl startServing(LPVOID pParam)

   if(server_process())
    AfxMessageBox(_T("Error Starting the VXI 11 Server."));

   AfxEndThread(0,TRUE); //I never get here.
   return 0;
 

//How I would like to stop the thread:
void myDlg::OnBnClickedQuit()

   DWORD threadStatus;
   endThread = 1; //static or extern that could be monitored if svc_run() 
                  //wasn't in a dll
   threadStatus = WaitForSingleObject(myThread->m_hThread, INFINITE);
   OnOk(); //for the ok modal to close the progam

 

//How I end up stopping my thread
void myDlg::OnBnClickedQuit()

   TerminateThread(myThread->m_hThread,1);
   OnOk(); //for the ok modal to close the progam

 


int server_process()

  //Portmap and server registration code
  .
  .
  .
  .
   svc_run(); //ideally I'd be able to monitor a global in here
   (void)fprintf(stderr, "svc_run returned\n");
#ifdef WIN32
   rpc_nt_exit();
#endif
   return(1);

 // end of server Process

// Function in the dll I'm calling
void svc_run()

#ifdef FD_SETSIZE
        fd_set readfds;
#else
      int readfds;
#endif /* def FD_SETSIZE */
#ifndef WIN32
    extern int errno;
#endif

    for (;;)  
#ifdef FD_SETSIZE
    readfds = svc_fdset;
#else
    readfds = svc_fds;
#endif /* def FD_SETSIZE */
#ifdef WIN32
    switch (select(0 /* unused in winsock */, &readfds, NULL, NULL,
#else
    switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
#endif
               (struct timeval *)0)) 
    case -1:
#ifdef WIN32
        if (WSAerrno == EINTR) 
#else
        if (errno == EINTR) 
#endif
            continue;
        
        perror("svc_run: - select failed");
        return;
    case 0:
        continue;
    default:
        svc_getreqset(&readfds);
       
   

【问题讨论】:

【参考方案1】:

嗯,答案就在你的问题中。您必须编写自己的svc_run() 并使用条件更改无限循环:

while(!done) 
  select(....)
  svc_getreqset(&readfds);

【讨论】:

以上是关于使用 MFC 清除 ONC RPC SVC_RUN() 退出的主要内容,如果未能解决你的问题,请参考以下文章

如何在 onc-rpc 中将字符串 (char*) 从服务器发送到客户端

C++:停止 RPC 服务

关于RPC

实现 RPC 的 C 库

使用 SUN RPC 释放内存

RPC、套接字和性能注意事项