Reputation: 717
I'm not sure whether std::thread
is supposed to be working under Cygwin. The only posts I find are years old and deal with compiler errors. So this problem is a bit different.
I am porting an application from Linux to Cygwin. It uses multiple threads with std::thread
and works except for one thing: In one place a call to std::thread::detach()
throws with Invalid argument
although std::thread::joinable()
returns true
.
I tried to built an example:
#include<thread>
#include<iostream>
#include<mutex>
#include<condition_variable>
std::thread* t;
std::mutex m;
std::condition_variable cv;
void func(void)
try
{
std::cout << "func" << std::endl;
if (t->joinable())
{
std::cout << "t is joinable" << std::endl;
t->detach();
delete t;
std::unique_lock<std::mutex> lck(m);
cv.notify_all();
}
}
catch(std::exception& e)
{
std::cout << "exception in func: " << e.what() << std::endl;
}
int main(void)
{
try
{
std::unique_lock<std::mutex> lck(m);
t=new std::thread(&func);
cv.wait(lck);
std::cout << "func finished" << std::endl;
cv.wait(lck);
}
catch(std::exception& e)
{
std::cout << "exception in main: " << e.what() << std::endl;
}
return(0);
}
I compile this on Linux with
g++ -std=c++0x -pthread example.cc
using gcc version 4.6.3
. It produces
func
t is joinable
func finished
then hangs indefinitely every time, which is expected behaviour due to the second, unmatched call to cv.wait()
.
On Cygwin I compile with
g++ -std=c++11 -pthread example.cc
using gcc version 4.9.3
.
It sometimes shows the above behaviour, sometimes it just shows
func
then exits with 0.
So I cannot reproduce my original error but rather get some more erratic behaviour.
Upvotes: 3
Views: 468
Reputation: 21576
First, you are likely a victim of spurious wake up....
An implementation is permitted to wake up a condition variable, so it is your responsibility to ensure that your condition is met ... You can do this by supplying an extra argument to cv.wait()
Please see: http://www.cplusplus.com/reference/condition_variable/condition_variable/wait/
Secondly, getting only "func" as an output with an exited zero(0) worries me. Cause that shouldn't happen at all.
At least "func has finished" should be printed because you flushed the stream : std::endl;
Upvotes: 1
Reputation: 10979
Your posted program contains undefined behavior. There two threads (main
and func
) race to access t
(that is ordinary, non-atomic raw pointer).
What happens with programs that contain undefined behavior includes (but is not limited to) nasal demons. So both linux and cygwin seem to work in that sense just the nasal demons happen to be of different kinds.
Upvotes: 1