1

I am trying to do the followings

class a{
public:
  void Start();
  void Tick();
  bool IsTimeOut;
};

void a::Start()
{
  boost::thread thread1(boost::bind(&a::Tick,this));
}
void a::Tick()
{
  while(!IsTimeOut)
  {
    boost::this_thread::sleep(boost::posix_time::millisec(1000));
  }
}

My environment is vs2005 and win7.

However, I always got the access violation in the debug.

s011208
  • 305
  • 4
  • 12
  • 6
    Your thread probably keeps running after the object has been destroyed. Post your complete test so that we can see what you are doing. – Maxim Egorushkin Aug 09 '11 at 08:25

2 Answers2

2

An access violation in this case would indicate that the thread is running beyond the lifetime of the a object.

IsTimeOut needs to either be atomic or protected by a mutex if it is written by another thread, otherwise your program might not work correctly, but this shouldn't cause the access violation.

You are destroying the boost::thread object immediately, and thus detaching the thread, so you have no way of waiting for it to finish. I would suggest storing the thread object as a member variable of a, and either joining with it in the destructor of a or providing an explicit wait() member function that joins with the thread.

Anthony Williams
  • 66,628
  • 14
  • 133
  • 155
  • I would too think that access a dead object is the cause of the problem here, and then no volatile keyword, synchronization or memory barriers in the world will change anything. – Lundin Aug 09 '11 at 19:28
0

IsTimeOut should be volatile if accessed from multiple threads, i.e.

volatile bool IsTimeOut;

Take a look at this DDJ article.

If you show more of your code and also explain how the IsTimeOut is changed it might be easier to say what goes wrong. In general, it looks like you have multiple threads and the first creates a, but what does that thread do then? Will a go out of scope and thus be destroyed? If so, then the timer thread will for sure have an access violation as the object is no longer available.

murrekatt
  • 5,961
  • 5
  • 39
  • 63
  • 2
    volatile is both not necessary and not sufficient for multi-threading. – Maxim Egorushkin Aug 09 '11 at 08:39
  • But if I change the "IsTimeOut" to while(1), it still happened. – s011208 Aug 09 '11 at 08:44
  • @Maxim, sure, but it's considered a good practice. Without more information what he's doing, it's not clear what's going wrong. At least it's good to change things in a proper way. – murrekatt Aug 09 '11 at 08:47
  • 2
    @murrekatt: using `volatile` for threading is **BAD** practice, not good practice! – Anthony Williams Aug 09 '11 at 08:49
  • @Anthony: in the case of a bool which controls the loop? – murrekatt Aug 09 '11 at 08:51
  • @murrekat: worth pointing out that volatile fails in the light of multi-core CPUs and CPU cache. It might be fine with explicit thread affinity, but as a rule it isn't OK to rely on volatile – sehe Aug 09 '11 at 08:52
  • @Anthony, in this case volatile should be present as it might otherwise be optimized by the compiler and will not be seen to be changed by the timer thread even if it is changed. – murrekatt Aug 09 '11 at 08:53
  • 1
    @murrekatt: `volatile` is the wrong tool for the job. Either use an atomic variable (e.g. `std::atomic`), or protect the flag with a mutex. Anything else is relying on compiler- and platform-specific guarantees. – Anthony Williams Aug 09 '11 at 08:58
  • @murrekatt volatile will force the threads to read/write memory instead of caching it in a register for example, which is necessary. But nothing forces both thread to see the same view of that memory location. Writing to a memory location in one thread does not mean that another thread will *see* the change at any specific time, and maybe writes will be seen out of order. On 'x86' you don't really see this problem in most common cases so you get away with it, but that doesn't mean it's correct. – jcoder Aug 09 '11 at 10:15
  • @JohnB: yes, I know this. I also see this kind of thing used in code bases I've been working with. I.e. a shutdown bool or ready or something like that which will be changed from another thread to affect a thread in a loop of some sort. – murrekatt Aug 09 '11 at 10:37
  • 1
    Sorry for being politically incorrect, but this is a lot of brainwashed comments. Soon as someone hears multi-threaded and volatile in the same post, they all go "nooo you can't use volatile for thread safety / synchronization". Well, who mentioned thread safety and synchronization in this post? There are many more issues when threading than that - threading can cause dangerous optimizations on many compilers and then volatile is the solution against that particular issue. But that doesn't mean it solves synchronization and instruction piping issues, those are entirely different things. – Lundin Aug 09 '11 at 19:19
  • 1
    Read this: http://stackoverflow.com/questions/6995310/is-volatile-bool-for-thread-control-considered-wrong/6996259#6996259 – Lundin Aug 09 '11 at 19:21