2013-03-23 28 views
7

Tôi đang sử dụng ZeroMQ để kết nối mạng trong ứng dụng của mình, hướng dẫn nêu rõ rằng bằng cách cung cấp cờ ZMQ_DONTWAIT cho thông số flags trong send hoặc recv làm cho chức năng không chặn luồng. Tuy nhiên, nó không hoạt động trong trường hợp của tôi bằng cách nào đó:Cờ ZMQ_DONTWAIT không hoạt động?

  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; 

in này:

abcdab 

tôi đã thực hiện một lớp ít để làm cho mọi việc dễ dàng hơn:

lớp khách hàng (sọc xuống từ khắp nơi " công cụ "chưa sử dụng" để đơn giản hóa)

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; 
}; 

và đây là chủ đề công nhân:

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; 
     } 
    } 
}; 

Sự cố tồn tại ở đây bằng cách nào đó. Tôi chỉ không biết tại sao nó không hoạt động.

Đây là cách tôi khởi động các sợi nhân:

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; 
} 

này tất cả có vẻ là đúng, vậy tại sao là recv/gửi chặn thread của tôi? Tại sao cờ không hoạt động?

+0

Thử kiểm tra lỗi trong chức năng gửi. "zmq_send() chức năng sẽ thất bại với errno đặt thành EAGAIN." –

+0

nếu đó là lỗi EAGAIN, thì không được chặn bất kỳ thứ gì. nhưng không có trở lại cho đến khi có thực sự bất cứ điều gì để gửi. và khi nào nó thành công. –

Trả lời

1

Nó được in "abcd" và sau đó "ab". Điều này có nghĩa là mã số

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

được thực hiện hai lần mặc dù mã bạn đã hiển thị ở cuối câu hỏi ngụ ý bạn chỉ thực hiện ToSend.push() một lần.

Bạn đã đính kèm trình gỡ lỗi để xem chuỗi nào đã bị treo và chuỗi cuộc gọi là gì?

  • Đặt tiêu chuẩn :: cout đằng sau một mutex/critsect để bạn chỉ biết một chuỗi đang viết cùng một lúc và báo cáo chuỗi của bạn.
  • Đặt từng đầu ra trên dòng riêng của nó để bạn không bỏ lỡ một lá thư do đệm.
  • Nếu bạn không chặn dữ liệu, bạn dự định nhận dữ liệu như thế nào? Bạn có cuộc gọi select/poll/WaitForSingleObject ở đâu đó không?
+0

hm đúng: o các vấn đề nhỏ tôi thấy trên đầu của tôi tất cả các thời gian: $ –

Các vấn đề liên quan