I have no idea why this doesn't work
#include <iostream>
#include <pthread.h>
using namespace std;
void *print_message(){
cout << "Threading\n";
}
int main() {
pthread_t t1;
pthread_create(&t1, NULL, &print_message, NULL);
cout << "Hello";
return 0;
}
The error:
[Description, Resource, Path, Location, Type] initializing argument 3
of 'int pthread_create(pthread_t*, const pthread_attr_t*, void*
(*)(void*), void*)' threading.cpp threading/src line 24 C/C++
Problem
You should declare the thread main as:
void* print_message(void*) // takes one parameter, unnamed if you aren't using it
Because the main thread exits.
Put a sleep in the main thread.
cout << "Hello";
sleep(1);
return 0;
The POSIX standard does not specify what happens when the main thread exits.
But in most implementations this will cause all spawned threads to die.
So in the main thread you should wait for the thread to die before you exit. In this case the simplest solution is just to sleep and give the other thread a chance to execute. In real code you would use pthread_join();
#include <iostream>
#include <pthread.h>
using namespace std;
#if defined(__cplusplus)
extern "C"
#endif
void *print_message(void*)
{
cout << "Threading\n";
}
int main()
{
pthread_t t1;
pthread_create(&t1, NULL, &print_message, NULL);
cout << "Hello";
void* result;
pthread_join(t1,&result);
return 0;
}
When compiling with G++, remember to put the -lpthread flag :)
From the pthread function prototype:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
The function passed to pthread_create must have a prototype of
void* name(void *arg)
This worked for me:
#include <iostream>
#include <pthread.h>
using namespace std;
void* print_message(void*) {
cout << "Threading\n";
}
int main() {
pthread_t t1;
pthread_create(&t1, NULL, &print_message, NULL);
cout << "Hello";
// Optional.
void* result;
pthread_join(t1,&result);
// :~
return 0;
}
Linkage. Try this:
extern "C" void *print_message() {...
Related
I am trying to understand the multithreading in c++. I am trying to call a function in another class using two threads as shown below. This function also returns the data.
vmgr.h
class VMGR{
public:
int helloFunction(int x);
};
vmgr.cpp
#include"vmgr.h"
#include<iostream>
int VMGR::helloFunction(int x){
std::cout<< "Hello World="<< x << std::endl;
return x;
}
main.cpp
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include "vadd.h"
#include<iostream>
#include<thread>
#include<chrono>
#include<algorithm>
#include "vmgr.h"
using namespace std::chrono;
int main(int argc, char* argv[]) {
VMGR vm;
std::thread t1(&VMGR::helloFunction, vm, 20);
std::thread t2(&VMGR::helloFunction, vm, 30);
t1.join();
t2.join();
return 0;
}
My syntax of return values from a thread is not correct. Please help me with how to handle the return values. Thank you in advance.
Most simple method obtaining results from the threads is using multiple pointers.
My simple solution follows:
#include<iostream>
#include<thread>
using namespace std::chrono;
class VMGR {
public:
void helloFunction(int x, int *res);
};
void VMGR::helloFunction(int x, int *res) {
std::cout << "Hello World=" << x << std::endl;
*res = x;
}
int main(int argc, char* argv[]) {
VMGR vm;
int outputs[2];
std::thread t1(&VMGR::helloFunction, vm, 20, &outputs[0]);
std::thread t2(&VMGR::helloFunction, vm, 30, &outputs[1]);
t1.join();
t2.join();
for (auto n : outputs)
std::cout << n << std::endl;
}
But, above is too simple code.
If your "hellofuntion()" have side effects, you must add synchronization codes.
I'm trying to make threads using C++'s standard library via functions.
#include <iostream>
#include <thread>
using namespace std;
void print()
{
printf("PRINT\n");
printf("PRINT2\n");
}
void createThread()
{
thread newThread(print);
}
int main()
{
createThread();
cin.get();
}
the program compiles and runs but once the thread is finished it creates a "debug error". Any thoughts?
The problem is that your thread object goes out of scope before you call its detach() or join() member.
Try this:
int main()
{
thread newThread(print);
...
newThread.join();
return 0;
}
If your "debug error" means the compiler error message, you should check if -pthread flag is set. That is compile the code with
$ g++ -std=c++11 main.cpp -pthread -o main
If your "debug error" means the runtime error, you should remember to join() after you create a thread.
source code:
#include <iostream>
#include <thread>
void print()
{
std::cout << "PRINT" << std::endl;;
std::cout << "PRINT 2" << std::endl;;
}
void create_thread()
{
std::thread print_thread(print);
print_thread.join(); // remember to join()
}
int main()
{
create_thread();
return 0;
}
In addition, you may pay attention to 4 additional points:
using namespace std is not recommended.
remember to join() after you create a thread
return 0 for main()
printf() is in stdio.h. use std::cout for iostream
I have a small solution in visual studio 2012. The solution consists of two projects (Scanner and TestApp), Scanner is a dll and TestApp is a small application using the dll.
I would like a function in the dll to run in a thread and to report its result back via a queue to the TestApp.
To test this I wrote a minimal application, but depending on how I launch the thread I get different results and I would like to understand why.
The Scanner.h file looks like this:
#pragma once
#include <iostream>
#include <string>
#include <stdint.h>
#include <atomic>
#include <future>
#include <thread>
#include "version.h"
#include "threadsafe_queue.h"
#include "capture_data.h"
#include "process_data.h"
#ifdef SCANNER_EXPORTS
#define SCANNER_API __declspec(dllexport)
#else
#define SCANNER_API __declspec(dllimport)
#endif
class Scanner
{
public:
static SCANNER_API void run();
static SCANNER_API void stop();
};
Scanner.cpp:
#include "stdafx.h"
#include "Scanner.h"
std::vector<std::future<int>> my_futures;
void Scanner::run()
{
CaptureData capture_data(1234);
auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);
my_futures.push_back(std::move(t));
}
void Scanner::stop()
{
for(int n=0; n<my_futures.size(); n++) {
auto e = std::move(my_futures.back());
e.get();
my_futures.pop_back();
}
}
The class CaptureData is defined in capture_data.h and capture_data.cpp.
capture_data.h:
#pragma once
#include <atomic>
#include <thread>
#include "iq_data.h"
#include "threadsafe_queue.h"
class CaptureData
{
public:
CaptureData(double freq_start);
void configure();
void get_data();
private:
double m_test;
};
capture_data.cpp
#include "stdafx.h"
#include "capture_data.h"
#include "Scanner.h"
ThreadsafeQueue<int> g_queue_1;
SCANNER_API ThreadsafeQueue<int> g_queue_2;
CaptureData::CaptureData(double test)
: m_test(test) {}
void CaptureData::get_data()
{
cout << "1: " << m_test << std::endl;
Sleep(5000);
cout << "2: " << m_test << std::endl;
g_queue_2.push(3);
cout << "Capture has now pushed data" << std::endl;
}
And finally the TestApp.cpp:
#include "stdafx.h"
#include "tchar.h"
#include <stdint.h>
#include <string>
#include "Scanner.h"
SCANNER_API extern ThreadsafeQueue<int> g_queue_2;
int _tmain(int argc, _TCHAR* argv[])
{
Scanner scanner;
scanner.run();
cout << "TestApp waiting for data..." << std::endl;
int data;
g_queue_2.wait_and_pop(data);
cout << "TestApp got data: " << data << std::endl;
scanner.stop();
return 0;
}
In Scanner.cpp I have tried to launch the thread in two different ways, the first way:
auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);
Second way is with a reference to the object "capture_data":
auto t = std::async(std::launch::async, &CaptureData::get_data, &capture_data);
The first way seems to work as I intended the application to work and I get the following printouts in my terminal:
TestApp waiting for data...
1: 1234
2: 1234
Capture has now pushed data
TestApp got data: 3
Press any key to continue...
If I use the second way I get:
TestApp waiting for data...
1: 6.95166e-310
2: 6.95166e-310
Capture has now pushed data
TestApp got data: 3
Press any key to continue...
So, what I do not understand is why the variable "m_test" get messed up in the second case.
I would very much appreciate if anyone could shed a light on this.
/M
In the following code:
void Scanner::run()
{
CaptureData capture_data(1234);
auto t = std::async(std::launch::async, &CaptureData::get_data, capture_data);
my_futures.push_back(std::move(t));
}
capture_data is a local variable that goes out of scope and gets destroyed when the function returns. If you pass a pointer to that variable into async that pointer becomes a dangling pointer causing undefined behaviour. That does not happen if you pass it by value, as you do in the above snippet.
You are trying to pass a pointer to a stack allocated object. This object is destructed at the end of the Scanner::run() method. Thus, the pointer is now pointing to invalid memory when the async function runs.
The first method works, because the capture_data variable is move constructed when it is passed to the function, therefore it still retains it's structure.
I recommend using lambda functions than passing the raw member function:
void Scanner::run()
{
CaptureData capture_data(1234);
auto t = std::async(std::launch::async, [capture=std::move(capture_data)]() { capture.get_data(); });
my_futures.emplace_back(t);
}
Even better is to construct the object inside the lambda function:
void Scanner::run()
{
auto t = std::async(std::launch::async, []() {
CaptureData capture_data(1234);
capture_data.get_data();
});
my_futures.emplace_back(t);
}
I am trying to create a input handler using multi threading with the SDL2 Library; however, when I try to put a thread in a class it won't compile and gives me this error...
error: cannot convert 'inputHandlerClass::getInput' from type 'int (inputHandlerClass::)(void*)' to type 'SDL_ThreadFunction {aka int (*)(void*)}'
I'm pretty sure that its the way I am passing the function name (fn) to the SDL_CreateThread function.
This is the source.cpp file
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_thread.h>
#include <SDL_mixer.h>
#include "..\include\gameClass.hpp"
#include "..\include\inputHandlerClass.hpp"
int main(int argc, char *argv[]){
inputHandlerClass inputHandler;
inputHandler.startThread();
std::cout << "hello world";
return 0;
}
This is the inputHandlerClass.hpp
#include <SDL_thread.h>
#include <iostream>
class inputHandlerClass{
private:
SDL_Thread *thread;
int threadReturnValue;
public:
inputHandlerClass();
int getInput(void *ptr);
void startThread();
};
//Default Constructor
inputHandlerClass::inputHandlerClass(){
this->thread = SDL_CreateThread(getInput, "inputThread", this);
}
int inputHandlerClass::getInput(void *ptr){
int cnt;
for(cnt= 0; cnt < 10; ++cnt){
std::cout << "counter: " << cnt << std::endl;
SDL_Delay(50);
}
return cnt;
}
void inputHandlerClass::startThread(){
SDL_WaitThread(this->thread, &this->threadReturnValue);
}
SDL_CreateThread expects a pointer to a regular function with int(void *ptr) signature as first parameter, however you are providing a non-static member function (not even a pointer because member functions aren't getting implicitly converted to a pointer). You should redeclare getInput as static. this pointer will be available as ptr.
#include <iostream>
namespace A {
void func();
}
void A::func()
{
extern char **environ;
std::cout << environ[0] << std::endl;
}
int main()
{
A::func();
return 0;
}
Like the code above, I just want to use the system-defined pointer **environ in A::func(), but g++ always says:
undefined reference to `A::environ'
How can I use the system-defined variable environ correctly?
Add
#include <unistd.h>
and environ must be in global scope.
So the code would look like this:
#include <iostream>
#include <unistd.h>
extern char **environ;
namespace A {
void func();
}
void A::func()
{
std::cout << environ[0] << std::endl;
}
int main()
{
A::func();
return 0;
}
You just need to declare environ at global scope, which is of course where it is defined, rather than within your function.
If you want to be a little cleaner about it and avoid unnecessary use of global variables, you can declare main this way:
int main(int argc, char* argv[], char* envp[])
Then simply pass envp to your function. It will work the same as the global.