[zeromq-dev] inproc: passing an object pointer between threads causing datarace?? (3.2.2 stable release)

John Jefferies j.jefferies at ntlworld.com
Wed Nov 28 00:29:41 CET 2012


On 27/11/2012 21:23, Kah-Chan Low wrote:
> Earlier this year someone floated the idea of passing an object 
> pointer between threads in the context of "inproc" protocol and there 
> was broad agreement that it could be done with no problem:
> http://comments.gmane.org/gmane.network.zeromq.devel/7300
>
> Right now I am in similar situation: I don't want to sacrifice speed 
> by needlessly serializing and de-serializing my objects.
> However, I am now very worried because Valgrind flags data race errors 
> in my code due to my passing of pointers around.
> I wrote the following simple program as an illustration:
>
> #include <boost/thread.hpp>
> #include <boost/bind.hpp>
> #include <algorithm>
> #include <zmq.hpp>
> #include <zmq_utils.h>
> #include <iostream>
>
> using namespace std;
>
> void dealer2router(zmq::context_t& context, size_t limit)
> {
>   zmq::socket_t skDealer(context, ZMQ_DEALER);
>   int hwm=0;
>   skDealer.setsockopt(ZMQ_SNDHWM, &hwm, sizeof(hwm));
>   skDealer.connect("inproc://i_love_zmq");
>   for (size_t i=0; i<limit; i++) {
>     int32_t *n = new int32_t; // this line is pass_pointer:19
>     *n = 4;
>     *n += 2;   // assign value of *n to 6, then
>     skDealer.send(&n, sizeof(int32_t*)); // send the pointer
>   }
> }
>
> void router_do_smth(zmq::context_t& context, size_t limit)
> {
>
>   zmq::socket_t skRouter(context, ZMQ_ROUTER);
>   int hwm=0;
>   skRouter.setsockopt(ZMQ_RCVHWM, &hwm, sizeof(hwm));
>   skRouter.bind("inproc://i_love_zmq");
>   for (size_t i=0; i<limit; i++) {
>     int32_t *n;
>     zmq::message_t msg;
>     skRouter.recv(&msg);
>     skRouter.recv(&n, sizeof(n));
>     cout << "I got " << *n << '\n';  // this line is pass_pointer:38
>     delete n;
>   }
> }
>
> int main (int argc, char *argv[])
> {
>   zmq::context_t context(1);
>   boost::thread_group threads;
>
>   const size_t iter=100;
>   threads.create_thread(boost::bind(router_do_smth, 
> boost::ref(context), iter));
>   zmq_sleep(5);
>   threads.create_thread(boost::bind(dealer2router, 
> boost::ref(context), iter));
>   threads.join_all();
> }
>
> .......
>
>
> This error can not be suppressed by using 
> CPPFLAGS=-DZMQ_MAKE_VALGRIND_HAPPY  to build zmq.
> I am usingv3.2.2 stable release.
>
> I have two questions:
> 1. I don't understand the error message above: how does accessing the 
> value of variable n have anything to do with the internals of ZMQ?
> 2. Is it possible for the compiler to rearrange the machine 
> instructions such that the assignment of value of n (i.e. *n=4; *n += 
> 2;) occurs after the message has been sent and received on the other 
> thread? In this case, is it possible for the program to output any 
> value other than '6' for 'n'?

A complete guess, probably wrong. Is it possible that valgrind is 
complaining that before the new allocation replaces it ,n in 
dealer2router() still has the same value as the previous iteration 
around the loop (and the same as the other thread is dereferencing). Try 
setting n=null after the send to see if that gets rid of the warning.

John

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20121127/2f73e864/attachment.htm>


More information about the zeromq-dev mailing list