【问题标题】:Multi threading for reading and writing to SERVER in c++用于在 C++ 中读取和写入 SERVER 的多线程
【发布时间】:2016-01-22 04:56:26
【问题描述】:

我有一个要求,我必须在套接字上写入,然后从套接字连续读取响应并处理数据。 我创建了 2 个类 A 和 B。A 有 write() 和 read() api,B 有 processdata() api。 我创建了从 A::read() 到 B::processdata() 的回调。 但是我正面临多线程问题,因为我是新手。 read() api 的线程必须始终运行,但是在处理 B::processdata() 中的数据时,服务器正在我丢失的套接字 read() 上发送更多数据。 请为此问题提出一些设计建议,以便我可以继续存储数据,而我的 processdata 函数可以完成其工作并可以再次回来读取数据(带有小示例)? 我正在考虑维护 3 个线程,每个 write 、 read 和 processdata 1 个。但是我不确定在完成 processdata 线程后如何返回读取线程。

很抱歉,这篇文章很长,但如果有人可以帮助我,我将不胜感激。

以下是我在项目中的高级代码设计。

 //A.cpp
        class A {
        public:
          void  write();
           void read(b* obj);
        }
        void A::write()
        { 
           //code to write to socket  

          }
        void A::read(b* obj)
        { 
           //code to read from socket  
          // if data received call below function 
          obj->processdata(buffer)
          }

    //B.cpp    
        class B {
        public:
            processdata(buffer)
        }

        void B::processdata(buffer)
        { 
           //code to processdaata from socket  
          }
//Main.cpp
        int main()
        {
          A* objA = new A;
          B* objB = new B;
          objA->write()
          while(1)
           {
             objA->read(objB)
            }
        }

【问题讨论】:

  • 为什么不能尝试使用临界区?据我了解,您问的是线程同步?
  • 您需要复制buffer 的内容或使用多个缓冲区,以便在处理早期数据的同时继续接收数据。您必须有一些方法来存储这些缓冲区,直到B 可以处理它们,同时让B 线程等待数据可用。 2 个线程之间的同步至关重要。
  • @Akhil:请原谅我的天真,但您是在谈论使用 semaphore/mutex 保护我的缓冲区吗?我的问题是,在处理数据时,我在套接字上阻塞读取,因为我的代码将处理数据。所以我需要帮助创建一个多线程模型。你能帮我举个小例子吗?
  • @1201ProgramAlarm 你能给我一个小例子吗?我会非常乐于助人,非常感谢。
  • 这不是一堆微不足道的代码。查找“生产者消费者问题”。

标签: c++ multithreading sockets client-server


【解决方案1】:

A.cpp

extern  CRITICAL_SECTION    g_cCritSec;
        class A {
        public:
          static void  write();
          static void read(void* obj);
        }
        void A::write()
        { 

           EnterCriticalSection(&g_cCritSec);
           //code to write to socket 
           LeaveCriticalSection(&g_cCritSec); 

        }
        void A::read(void* obj)
        { 
           EnterCriticalSection(&g_cCritSec);
           while(1)
           {
              //code to read from socket  
              // if data received call below function 
              // send separate copy of buffer to avoid overrite
              uintptr_t Thread2 = _beginthread( B::processdata, 0, (void *) buffer); 

              //obj->processdata(buffer)
           }
           LeaveCriticalSection(&g_cCritSec);
        }

B.cpp

  extern    CRITICAL_SECTION    g_cCritSec;
        class B {
        public:
            static processdata( void *buffer)
        }

        void B::processdata(void *buffer)
        {  
           Buffer *bufferReceive = (Buffer*)buffer;
           //code to processdaata from socket   
        }

Main.cpp

CRITICAL_SECTION    g_cCritSec;
        int main()
        {

          InitializeCriticalSection(&g_cCritSec); 
          B* objB = new B;
          objA->write();
          uintptr_t Thread1 = _beginthread( A::read, 0, (void *) objB); 

          DeleteCriticalSection(&g_cCritSec); 
        }

这个答案对你有帮助吗?一个最小的多线程应用程序,它将启动 Thread1 作为静态成员函数 A::Read 作为例程(我们需要将成员函数定义为静态以用作线程回调)。从Read 函数,它将启动另一个线程,并将buffer 的副本传递给它。这里两个线程将同时执行

【讨论】:

  • 哇。正是我正在寻找的答案。谢了哥们。我还有一个查询,出于线程和套接字的目的,我应该使用 Boost Libs 吗?我读到 c++11 有线程支持,但是当我使用“thread t”时,我收到错误消息“错误:'thread' 不是 'std' 的成员”:(另外,我必须使这段代码独立于操作系统,因为可以在 Linux 和 windows 上交叉编译。请您也就此提出一些建议吗?
  • 如果它正在解决您的问题,请将其作为已接受的答案。尝试包含 pthread.h 并使用 pthread_t(不是 pthread t)类来创建线程。请参考 pthread_create 函数来创建 posix 线程。
猜你喜欢
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多