2013-03-23 20 views
7

मैं अपनी प्रशंसा में नेटवर्किंग के लिए ज़ीरोएमक्यू का उपयोग कर रहा हूं, मैनुअल का कहना है कि ZMQ_DONTWAIT पैरामीटर पैरामीटर send या recv में थ्रेड को थ्रेड को अवरुद्ध नहीं करता है। अभी तक यह किसी भी तरह मेरे मामले में काम नहीं करता है:ZMQ_DONTWAIT ध्वज काम नहीं करता है?

  std::cout << "a"; 
      if(ToSend.try_pop(send)) 
      { 
       std::cout << "b"; 
       local.send(send.data(),send.size(),ZMQ_DONTWAIT); 
      } 
      std::cout << "c"; 
      if(local.recv(recv.data(),Networking::max_packet,ZMQ_DONTWAIT)) 
       std::cout << "Received: " << (char*)recv.data() << std::endl; 
      std::cout << "d" << std::endl; 

इस प्रिंट:

abcdab 

मैं एक छोटे से वर्ग चीजों को आसान बनाने के लिए किए गए:

ग्राहक वर्ग (सभी से नीचे धारीदार " अप्रयुक्त ", सरलीकरण के लिए)

class client 
{ 
public: 
    client() 
    { 

    } 
    inline bool init(unsigned short threads = 1) 
    { 
     Running = true; 
     context = zmq_init (threads); 
     if(context == NULL) 
      return false; 
     socket = zmq_socket (context, ZMQ_REQ); 
     if(socket == NULL) 
      return false; 
     return true; 
    } 
    inline int connect(const char * address, unsigned short port) 
    { 
     return zmq_connect(socket,string_format("tcp://%s:%d",address,port).c_str()); 
    } 
    inline bool send (void *data, size_t len_, int flags_ = 0) 
    { 
     message_t request (len_); 
     memcpy ((void *) request.data(), data, len_); 
     int rc = zmq_send (socket, request.data(), request.size(), flags_); 
     if (rc >= 0) 
      return true; 
     if (rc == -1 && zmq_errno() == EAGAIN) 
      return false; 
     throw error_t(); 
    } 
    inline bool recv (void * data, size_t len_, int flags_) 
    { 
     message_t reply(len_); 
     int rc = zmq_recv (socket, reply.data(), len_, flags_); 
     if (rc >= 0) 
     { 
      memcpy (data,(void *)reply.data(), reply.size()); 
      return true; 
     } 
     if (rc == -1 && zmq_errno() == EAGAIN)return false; 
     throw error_t(); 
    } 
    inline bool IsRunning() 
    { 
     return Running; 
    } 
private: 
    void * context; 
    void * socket; 
    std::atomic<bool> Running; 
}; 

और यहाँ सामान कार्यकर्ता धागा है:

namespace Data 
{ 
    Concurrency::concurrent_queue <message_t> ToSend; 
    void Processor(char * address, unsigned short port, unsigned short threads) 
    { 
     client local; 
     if(!local.init(threads))return; 
     if(local.connect(address,port) != 0)return; 
     message_t recv(Networking::max_packet); 
     message_t send(Networking::max_packet); 
     while(local.IsRunning()) 
     { 
      std::cout << "a"; 
      if(ToSend.try_pop(send)) 
      { 
       std::cout << "b"; 
       local.send(send.data(),send.size(),ZMQ_DONTWAIT); 
      } 
      std::cout << "c"; 
      if(local.recv(recv.data(),Networking::max_packet,ZMQ_DONTWAIT)) 
       std::cout << "Received: " << (char*)recv.data() << std::endl; 
      std::cout << "d" << std::endl; 
     } 
    } 
}; 

समस्या किसी भी तरह मौजूद है। मुझे नहीं पता कि यह क्यों काम नहीं कर रहा है।

यह मैं कैसे कार्यकर्ता धागा लांच है:

int Thread(char * address, unsigned short port, unsigned short threads) 
{ 
    std::thread data(Data::Processor,address,port,threads); 
    data.detach(); 
    while(!Data::status){} 
    return Data::status; 
} 
int main(int argc, char* argv[]) 
{ 

    std::thread s(Server::RUN); 

    Client::message_t tosend(14); 
    memcpy((void*)tosend.data(),"Hello World !\0",14); 

    Client::Data::ToSend.push(tosend); 

    std::cout << Client::Thread("127.0.0.1",5555,1) << std::endl; 

    s.join(); 
    return 0; 
} 

यह सब सही हो रहा है, तो क्यों recv/मेरी धागा अवरुद्ध भेज रहा है? ध्वज क्यों काम नहीं करता है?

+0

प्रेषण कार्य में त्रुटियों की जांच करने का प्रयास करें। "zmq_send() फ़ंक्शन इग्नो सेट के साथ विफल हो जाएगा।" –

+0

यदि यह एक ईगल त्रुटि होगी, तो इसे किसी भी चीज़ को अवरुद्ध नहीं करना चाहिए। फिर भी वास्तव में कुछ भी भेजने के लिए कोई वापसी नहीं है। और जब यह सफलतापूर्वक भेज दिया जाता है। –

उत्तर

1

यह "abcd" और फिर "ab" मुद्रित किया गया। इसका मतलब है कि कोड

std::cout << "a"; 
if(ToSend.try_pop(send)) 
{ 
    std::cout << "b"; 

दो बार मार डाला गया था, हालांकि कोड आप प्रश्न के अंत में पता चला है का तात्पर्य है कि आप केवल ToSend.push() एक बार किया था।

क्या आपने यह देखने के लिए एक डिबगर संलग्न किया था कि कौन सा धागा लटका था और यह कॉलस्टैक क्या है?

  • std :: cout को mutex/critsect के पीछे रखें ताकि आप जानते हों कि एक समय में केवल एक धागा लिख ​​रहा है, और रिपोर्ट करें कि आप कौन सा धागा हैं।
  • प्रत्येक आउटपुट को अपनी लाइन पर रखें ताकि आप बफरिंग के कारण कोई पत्र न चूकें।
  • यदि आप डेटा के लिए ब्लॉक नहीं करते हैं तो आप इसे प्राप्त करने की अपेक्षा कैसे कर रहे हैं? क्या आपके पास कहीं भी एक चयन/मतदान/WaitForSingleObject कॉल है?
+0

एचएम सही: o छोटे मुद्दों को मैं अपने सिर पर हर समय देखता हूं: $ –

संबंधित मुद्दे