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
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev