Aug 10, 2009 at 8:23pm UTC
hello all,
I lack an understanding of the details of how threads interact in C++...
I have a number of threads
extern "C" void* My_Thread(void* arg)
{
...
pthread_mutex_lock( &my_mutex);
v_if.push_back(my_struct);
pthread_mutex_unlock( &my_mutex);
...
}
that update a vector v_if in my main class (a gtkmm window class);
however this only seems to work reliably when I precede the launching of the threads by a
v_if.reserve(MY_BIG_MAX);
in my main class; can someone explain the reason for this?
what could I be doing wrong?
greetings, Danny.
Aug 11, 2009 at 5:29am UTC
What does it do when you *don't* put the reserve in there? Does it crash?
Aug 11, 2009 at 8:57am UTC
If a datastructure is being changed and possibly simulateously accessed by more than one thread, it must be protected by a sychronisation object of some kind, typically a mutex.
Aug 11, 2009 at 6:53pm UTC
What does it do when you *don't* put the reserve in there? Does it crash?
well, the results differ from time to time, but "crash" is the best general description.
If a datastructure is being changed and possibly simulateously accessed by more than one thread, it must be protected by a sychronisation object of some kind, typically a mutex.
that's why I added the
pthread_mutex_(un)lock( &my_mutex);
in each thread...
Aug 11, 2009 at 6:55pm UTC
Are you compiling with -D_REENTRANT ?
[edit: or-D _THREAD_SAFE ?]
Last edited on Aug 11, 2009 at 6:56pm UTC
Aug 11, 2009 at 7:57pm UTC
yes:
g++ -DORBIT2=1 -pthread -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API ...
Aug 12, 2009 at 1:20pm UTC
Are you sure all accesses of the vector are protected by mutexes?
Are you keeping iterators into the vector around after releasing the mutex?
(Iterators in vectors are potentially invalidated on push_back()s)
Aug 12, 2009 at 7:07pm UTC
there is only one access where items are added to the vector, and I don't use iterators for accessing the items ...
for the really adventurous: complete code is available in
http://quintl.svn.sourceforge.net/viewvc/quintl/src/
and the line in question is line 61
v_if.reserve(...);
in
pix_window.cc ...
the items are added through
pix::gui::pix_window::Find_All_Images( )
-->
extern "C" void* StartPThread_Find_Images(void* arg)
-->
pix::gui::pix_window::Find_Images( string &file_root_dir, bool recursive_search)
-->
pix::gui::pix_window::Add_File_To_Images( string &file_name, struct stat *stat_buf)
-->
v_if.push_back(i_f);
Last edited on Aug 12, 2009 at 7:11pm UTC
Aug 25, 2009 at 8:22pm UTC
ok, I finally solved this by:
- making a new version of the program without any threads,
- still seeing it crash
- and then rediscovering valgrind
I had a faulty element access somewhere
v_if[t].finished = PIX_FILE_IMAGE_OK;
that was certain to go out of range under certain conditions.
with the
v_if.reserve(MY_BIG_MAX);
this had no real impact, whereas without it, the program crashed later on ...
my mistake...