shared_lock( ) causes Segmentation Fault in CentOS 5.5 x64?

Dear Pals,
I wrote a server program, and there is a class called "apInfoMutex",
which can store client's file descriptor info and what messages they sent;
the class code is as below:
---
class apInfoTable{
public:
apInfoTable();
boost::shared_mutex rwMutex;
void addFD(int apfd, char *srvceType, vector<string> *codeList);
void delFD(int apfd);
bool getFD(list<int> *des, char *srvceType, char *srvceCode);
private:
boost::unordered_map
tableFD;
boost::unordered_map

On Mar 14, 2011, at 11:39 PM, DesertFish wrote:
Dear Pals,
I wrote a server program, and there is a class called "apInfoMutex", which can store client's file descriptor info and what messages they sent; the class code is as below: --- class apInfoTable{ public: apInfoTable(); boost::shared_mutex rwMutex; void addFD(int apfd, char *srvceType, vector<string> *codeList); void delFD(int apfd); bool getFD(list<int> *des, char *srvceType, char *srvceCode);
private: boost::unordered_map
> tableFD; boost::unordered_map
, boost::unordered_set<int> > tablePush; }; --- there is just one apInfoTable as global declaration in my program, but there would be two or more threads to calling these public method at the same time, and there is a method called "getFD()" in this class, the code is as below: --- bool apInfoTable::getFD(list<int> *des, char *type, char *code){ bool flag=false; boost::shared_lockboost::shared_mutex lock(rwMutex); for(boost::unordered_set<int>::iterator it=tablePush[pair
(type, code)].begin();it!=tablePush[pair (type, code)].end ();it++){ flag=true; des->push_back(*it); } return flag; } --- I found if I calling getFD() method like this: char type[12]; char code[32]; list<int> fdList; memset(type, 0x00, sizeof(type)); memset(code, 0x00, sizeof(code)); memcpy(type, "My Type", sizeof("My Type")); memcpy(code, "My Code", sizeof("My Code")); fdList.clear(); bool rc=getFD(&fdList, type, code); I will got "Segmentation Fault" problem, but if I put different parameter like this: bool rc=getFD(&fdList, "My Type", "My Code");
or using boost::mutex instead of shared_lock() and shared_mutex in getFD(), there wouldn't be any problem when running program.
is there any problem with my code? or did I use shared_lock() and shared_mutex incorrectly?
P.S--I tried using unique_lock or scoped_lock instead of shared_lock(), but there is just no any problem when I using normal boost::mutex
It looks like you are locking your structure in "read mode" and then writing to it:
boost::shared_lockboost::shared_mutex lock(rwMutex); for(boost::unordered_set<int>::iterator it=tablePush[pair
(type, code)].begin();it!=tablePush[pair (type, code)].end ();it++){ flag=true; des->push_back(*it); }
If you want to lock it in write mode do this: boost::unique_lockboost::shared_mutex lock(rwMutex); -Howard

Howard Hinnant
It looks like you are locking your structure in "read mode" and then writing to it:
boost::shared_lockboost::shared_mutex lock(rwMutex); for(boost::unordered_set<int>::iterator it=tablePush[pair
(type, code)].begin();it!=tablePush[pair (type, code)].end ();it++){ flag=true; des->push_back(*it); } If you want to lock it in write mode do this:
boost::unique_lockboost::shared_mutex lock(rwMutex);
-Howard
Hi Howard, Did you mean des->push_back(*it) in this method? actually in my program, there is an independent fdList(which called "des" in the method) in every thread, in other words every thread have its own fdList and just reference into this method when they calls this method. In my opinion, if every fdList is declared independently in each thread, they won't take effect each other when they are referenced into this method and ask to push_back what this method found in the loop to them. did this also have to use write lock? I thought it's still read mode(If I'm incorrect please tell me) (this method push_backs what it found into every fdList every thread owned, they didn't push_backs in the same "global" fdList at the same time. This method just "read" the same tablePush without write it, that's why I think it's just in read mode..) Or did you mean the other place in my code is incorrect? Thank you Zap

Howard Hinnant
On Mar 14, 2011, at 11:39 PM, DesertFish wrote:
It looks like you are locking your structure in "read mode" and then writing
to it:
boost::shared_lockboost::shared_mutex lock(rwMutex); for(boost::unordered_set<int>::iterator it=tablePush[pair
(type, code)].begin();it!=tablePush[pair (type, code)].end ();it++){ flag=true; des->push_back(*it); } If you want to lock it in write mode do this:
boost::unique_lockboost::shared_mutex lock(rwMutex);
-Howard
Hi Howard,
I just tested a simple case,
which just lock the read lock and print out the result
of tablePush.size(), like this:
bool getFD(list<int> *des, char *type, char *code){
bool flag=false;
boost::shared_lockboost::shared_mutex lock(rwMutex);
cout<

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday, March 16, 2011, Zap wrote:
I just tested a simple case, which just lock the read lock and print out the result of tablePush.size(), like this:
bool getFD(list<int> *des, char *type, char *code){ bool flag=false; boost::shared_lockboost::shared_mutex lock(rwMutex); cout<
(type, code)].size()< but it still happens Segmentation Fault...
could anyone know what's the problem is?
operator[] on maps can modify the map. Maybe you want to use find() instead? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEARECAAYFAk2AtF8ACgkQ5vihyNWuA4U8dwCgqo2WMSY9JLSbNL8x1je8Qd2Y XtEAoLkH9S0m9LE8nMH4idirsz2UsNi3 =TB03 -----END PGP SIGNATURE-----

Frank Mori Hess
operator[] on maps can modify the map. Maybe you want to use find() instead?
Hi Frank,
I'll try it later, thanks for your answer,
Is there any difference of performance between
using operator[] and .find()?
especially in frequently finding key/value of pair

On Thu, 17 Mar 2011 15:48:37 +0100, Zap
Frank Mori Hess
writes: operator[] on maps can modify the map. Maybe you want to use find() instead?
Hi Frank,
I'll try it later, thanks for your answer,
Is there any difference of performance between using operator[] and .find()?
Performance difference?!? Do you realize how much new/delete operations
you trigger by constructing pair
especially in frequently finding key/value of pair
in boost::unordered_map , boost::unordered_set<int> >. and another question is, could I use container in container such as what I wrote(unordered_set as value in unorder_map)? is this kind of structur undefine-behaviour or it's acceptable?
if it's acceptable, did this kind of structure will cause decrasing of performance or won't?
You may use these constructs, but you must be very carefully not to trigger occasionally deep copy when not intended to.
if it will, what kind of instead structure could I use to satisfy what I need to do?
It all depends on your project and associated performance requirements. Variants include using indices instead of string pairs (think of atoms in xlib), I would definetely use pointers/smart_pointers as values in the map instead complex values itself or some kind of indices to other tables if pointers are not suitable. Btw the integer set, which you use as the map value, may be implemented much more effeciently as bitset if the range for your integers is small. // Have you noticed how gently have we drifted away from the topic theme ;) -- Slava
participants (5)
-
DesertFish
-
Frank Mori Hess
-
Howard Hinnant
-
Viatcheslav.Sysoltsev@h-d-gmbh.de
-
Zap