I am trying out some simple boost::thread code, as follows:
#include <iostream>
#include <boost/thread.hpp>
void InputLoop()
{
std::cout << "Loop start" << std::endl;
int y = 0;
while (1)
{
std::cout << "y = " << y << std::endl;
y++;
}
std::cout << "Loop end" << std::endl;
}
int main()
{
std::cout << "Main start" << std::endl;
boost::thread t(InputLoop);
t.start_thread();
while (1)
{
int x = 0;
}
std::cout << "Main end" << std::endl;
return 0;
}
This gives the output:
Main start
Loop start
y = 0
y = 1
y = 2
.
.
.
The program has unexpectedly finished
So, it is crashing during InputLoop(). The value of y when the crash occurs varies between different runs, and ranges from about 0 to about 10000.
What's going on?
You shouldn't call start_thread?
This is not required, as it's a leaked internal implementation detail:
https://svn.boost.org/trac/boost/ticket/9632
In my code I accidentally called this method and it resulted in my callback being started twice.
So you get unsynchronized access to std::cout, y which leads to Undefined Behaviour
The fix is found in this commit: https://github.com/boostorg/thread/commit/750c849b0f0dff79a289111955260a4147ac7f59
Even though there is a public method start_thread in class thread, it isn't in the documentation. That's for a reason:
Launching threads
A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. [...]
If you wish to construct an instance of boost::thread with a function or callable object that requires arguments to be supplied, this can be done by passing additional arguments to the boost::thread constructor:
Regardless which constructor you use, the thread is already running:
// <boost/thread/detail/thread.hpp>
template <
class F
>
explicit thread(BOOST_THREAD_RV_REF(F) f
//, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
{
start_thread();
}
How's start_thread defined?
void start_thread()
{
if (!start_thread_noexcept())
{
boost::throw_exception(thread_resource_error());
}
}
start_thread_noexcept is actually not in a header, but part of libboost_thread:
// boost/lib/thread/src/thread.cpp
bool thread::start_thread_noexcept()
{
thread_info->self=thread_info;
int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get());
if (res != 0)
{
thread_info->self.reset();
return false;
}
return true;
}
You actually created two threads. And it's (probably) the thread_proxy implementation that creates your behaviour.
Related
I'm trying to call std::thread::joinable() from a thread itself. However the returned value is false in the beginning even when the thread is supposed to be active. For example with the following piece of code:
#include <iostream>
int main()
{
std::thread thethread;
int a = 0;
auto thefun = [&]() {
a++;
a++;
std::cout << thethread.joinable() << std::endl;
std::cout << thethread.joinable() << std::endl;
std::cout << "msg2 from thefun" << std::endl;
std::cout << thethread.joinable() << std::endl;
};
thethread = move(std::thread(thefun));
thethread.join();
return 0;
}
Output:
0
1
msg from thefun
1
I don't understand why the fist call to thethread.joinable() returns false whereas it starts to return true when std::cout is called. I have the feeling that this is caused by my silly mistake, I hope someone could enlighten me. Perhaps I shouldn't call joinable() in the thread itself?
I'm messing around with multithreading in c++ and here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <thread>
void read(int i);
bool isThreadEnabled;
std::thread threads[100];
int main()
{
isThreadEnabled = true; // I change this to compare the threaded vs non threaded method
if (isThreadEnabled)
{
for (int i = 0;i < 100;i++) //this for loop is what I'm confused about
{
threads[i] = std::thread(read,i);
}
for (int i = 0; i < 100; i++)
{
threads[i].join();
}
}
else
{
for (int i = 0; i < 100; i++)
{
read(i);
}
}
}
void read(int i)
{
int w = 0;
while (true) // wasting cpu cycles to actually see the difference between the threaded and non threaded
{
++w;
if (w == 100000000) break;
}
std::cout << i << std::endl;
}
in the for loop that uses threads the console prints values in a random order ex(5,40,26...) which is expected and totally fine since threads don't run in the same order as they were initiated...
but what confuses me is that the values printed are sometimes more than the maximum value that int i can reach (which is 100), values like 8000,2032,274... are also printed to the console even though i will never reach that number, I don't understand why ?
This line:
std::cout << i << std::endl;
is actually equivalent to
std::cout << i;
std::cout << std::endl;
And thus while thread safe (meaning there's no undefined behaviour), the order of execution is undefined. Given two threads the following execution is possible:
T20: std::cout << 20
T32: std::cout << 32
T20: std::cout << std::endl
T32: std::cout << std::endl
which results in 2032 in console (glued numbers) and an empty line.
The simplest (not necessarily the best) fix for that is to wrap this line with a shared mutex:
{
std::lock_guard lg { mutex };
std::cout << i << std::endl;
}
(the brackets for a separate scope are not needed if the std::cout << i << std::endl; is the last line in the function)
I created decorator function to add functionality to existing functions. The program outputs correct function pointer addresses along with an elapsed time to iterate 10 x helloworld as expected.
Yet, if I change decorator function to take the original_function by value (FunctionPointer original_function), the program terminates with a segmentation fault, which I don't get the reason why it fails.
#include <iostream>
#include <chrono>
typedef void (*FunctionPointer)();
auto
decorator(FunctionPointer && original_function) // if changed to FunctionPointer original_function, it causes segmentation fault when the closure(lambda expression) is called later on
{
std::cout << "Decorator: " << (void*)original_function << std::endl; // 0x558072fb0b90
return [&]()
{
std::cout << "Decorator: " << (void*)original_function << std::endl; // 0x558072fb0b90 but 0x0 when original_function passed by value
auto t0 = std::chrono::high_resolution_clock::now();
original_function();
auto duration = std::chrono::high_resolution_clock::now() - t0;
std::cout << "\nElapsed " << duration.count() * 1000.0f << " ms\n";
};
}
void
helloworld(void)
{
for (auto i = 0; i < 10; i++)
std::cout << "Hello, World!\n";
}
int
main(void)
{
std::cout << "Main: " << (void*)helloworld << std::endl; // 0x558072fb0b90
auto my_helloworld = decorator(helloworld);
my_helloworld();
return 0;
}
The difference is that when you pass the function by value, the parameter passed into the lambda is a reference to the function parameter, which goes out of scope when decorator returns. When you later call the returned lambda, you reference this out of scope variable, which is Undefined Behavior.
It works when you pass by universal reference, the parameter passed to decorator is a reference, which is passed to the lambda. So it is still valid later when you call the lambda.
You may be able to change your lambda to pass by value (use [=]) to get the changed version to work.
I was trying to demo to a collegue why you'd better pass const references to functions doing read only operations with the following code. To my surprise it prints "It's safe!", even if I'm changing the value of the passedBool while the other thread is sleeping.
I'm trying to find out if I made a typo somewhere, if the compiler optimizes the code and passes passedBool by copy to avoid some overhead or if starting another thread creates a local copy of passedBool.
class myClass
{
public:
myClass(bool& iBool)
{
t = thread(&myClass::myMethod,this,iBool);
}
~myClass()
{
t.join();
}
private:
thread t;
void myMethod(bool& iBool)
{
this_thread::sleep_for(chrono::seconds(1));
if(iBool)
cout << "It's safe!" << endl;
else
cout << "It's NOT safe!!!" << endl;
}
};
void main()
{
bool passedBool = true;
cout << "Passing true" << endl;
myClass mmyClass(passedBool);
cout << "Changing value for false" <<endl;
passedBool = false;
cout << "Expect \"It's NOT safe!!!\"" <<endl;
}
The arguments to the thread function are moved or copied by value. If
a reference argument needs to be passed to the thread function, it has
to be wrapped (e.g. with std::ref or std::cref).
from here
I'm trying to write a small piece of code that just makes using CreateThread() slightly more clean looking. I can't say that I'm really intending on using it, but I thought it would be a fun, small project for a newer programmer like myself. Here is what I have so far:
#include <iostream>
#include <windows.h>
using namespace std;
void _noarg_thread_create( void(*f)() )
{
cout << "Thread created...\n" << endl;
Sleep(10);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, NULL, 0, NULL);
}
template <typename T>
void _arg_thread_create( void(*f)(T), T* parameter)
{
cout << "Thread created...\n" << endl;
Sleep(10);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)*f, parameter, 0, NULL);
}
void printnums(int x)
{
for(int i = x; i < 100; i++)
{
cout << i << endl;
}
}
void printnumsnoarg()
{
for(int i = 0; i < 100; i++)
{
cout << i << endl;
}
}
int main()
{
cin.get();
_noarg_thread_create( &printnumsnoarg );
cin.get();
int x = 14;
_arg_thread_create( &printnums, &x );
cin.get();
}
Basically I have two functions that will call two different presets for CreateThread: one for when a parameter is needed in the thread, and one for when no parameter is needed in the thread. I can compile this with the g++ compiler (cygwin), and it runs without any errors. The first thread gets created properly and it prints out the numbers 0-99 as expected. However, the second thread does not print out any numbers (with this code, it should print 14-99). My output looks like this:
<start of output>
$ ./a.exe
Thread created...
0
1
2
3
.
.
.
97
98
99
Thread Created...
<end of output>
Any ideas why the second thread isn't working right?
you actually seem to miss you're passing a pointer to your printnums(int x) function. As the storage location of x in your main function will be a lot bigger than 100 your loop never runs.
You should try to change printnums to:
void printnums(int *x)
{
for(int i = *x; i < 100; i++)
{
cout << i << endl;
}
}
I guess everything will work as expected then.