pthread_create error in C++ (pthread inside class) - c++

I have this C++ code, where i try to create a pthread, and i got 4 errors:
Can anyone please help?
Thanks in advance.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
static void* func(void*);
class Test
{
public:
pthread_t *threadId;
pthread_create(threadId, NULL, func, NULL);
};
static void* func(void *arg)
{
printf("Thread function called\n");
}
int main()
{
Test();
}
Compiling:
# g++ simplepThread.cc -lpthread
simplepThread.cc:11: error: ‘threadId’ is not a type
simplepThread.cc:11: error: expected identifier before ‘__null’
simplepThread.cc:11: error: expected ‘,’ or ‘...’ before ‘__null’
simplepThread.cc:11: error: ISO C++ forbids declaration of ‘pthread_create’ with no type
If i use the thread function as a "C" linkage:
extern "C" void* func(void *arg)
{
printf("Thread function called\n");
}
Error faced is:
simplepThread.cc:7: error: previous declaration of ‘void* func(void*)’ with ‘C++’ linkage
simplepThread.cc:15: error: conflicts with new declaration with ‘C’ linkage

You can't call functions in class declaration. In class declaration you can only declare (and possibly define) its members. And
pthread_create(threadId, NULL, func, NULL);
is not a valid member function definition.
The whole class Test seems to be redundant.
static void* func(void *arg)
{
printf("Thread function called\n");
}
int main()
{
pthread_t threadId;
pthread_create(&threadId, NULL, func, NULL);
}
Should work fine.
I fixed also another problem - you tried to pass an uninitialized pointer (threadId) to a function that expects a variable address.
UPDATE
About the linkage - you have a prototype with default (C++ linkage)
void* func(void *arg);
And definition with C linkage
extern "C"
{
void* func(void *arg)
{
....
}
}
So they conflict. change prototype to
extern "C"
{
void* func(void *arg);
}
And it will be OK

There are a number of issues with your code. First of all, you need to declare a constructor function for the Test class, and given how you used the code, I would put the pthread_create() call inside the constructor. Secondly, while pthread_create() takes as its first argument a pthread_t* argument, this means that that argument is being used as an output parameter and the pointer should point to the actual memory/variable where the thread ID for the newly created thread will be placed.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
static void* func(void*);
class Test
{
public:
pthread_t threadId;
Test() {
pthread_create(&threadId, NULL, func, NULL);
}
};
static void* func(void *arg)
{
printf("Thread function called\n");
}
int main()
{
Test();
}
In general when you are doing multi-threaded code, you also want to ensure that the threads are destroyed when you are finished with them, or keep track of when they die on their own. For example, if you create a "worker" thread that will be used to process work in the background asynchronously, then you will often want to have a mutex-protected queue for the main thread to pass work to the worker thread. You would often also want some semaphore or other "safe" signaling system to cause the worker thread to die safely when the program wants to exit, with a back-signaling mechanism so the main thread knows when the worker has died and it is now safe to clean up the shared data structures. (i.e., putting a piece of work in the job queue that simply says "die", and having the worker reply "dying" before exiting)
Implementing correct multi-threaded code is non-trivial, and you have to worry about a wide range of issues, such as deadlock and race conditions, that simply do not occur with single-threaded code. I strongly recommend that you read about, and ensure that you fully understand, these and other topics.

Related

C++ composition without using the heap in embedded systems

I'm fairly new to C++, this is also my first post on here. I'm trying to use C++ in an embedded systems project so I can take the OOP approach. I'm using the AVR crosspack toolchain (AVR G++ compiler)
My problem is this:
From what i've read, the heap should not be used for dynamic memory allocation in embedded systems. In any case, there is no implementation for "new" in AVR G++ anyway. I'm using composition, starting with a USART driver (lets call it a service), and a logger (singleton pattern, and also a service).
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, however when I try to compose the objects needed in this way I get the following error:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
My sense is that my syntax for passing in an object as a constructor parameter is wrong, but I'm not sure what it should be as all the examples i can find use the "new" keyword in the constructor definition to create the object on the free store. Can anyone help?
The Code:
In "usart.h":
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
In "logger.h":
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
In "logger.cpp"
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
In "main.cpp":
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
It depends. I'm currently in an embedded project with maximum safety-related requirements, and we use new, but not delete. So we have a heap, but don't allocate "dynamically", because all allocated objects are kept during the runtime.
In any case, there is no implementation for "new" in AVR G++ anyway.
Is this true? I never checked... It might be necessary to provide a heap before being able to use new.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
This is a good idea. ;-) It helps unit-testing.
For your syntactical and design problems: This is how I would write your sources.
"usart.h":
All methods are non-static to have access to member variables.
The const attribute on a return type is doing nothing. Did you mean to declare the method constant? Then const belongs after the parameter list. However, this attribute might be wrong if such a method changes any member variable.
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
Just give and store a reference to the USART to avoid a copy.
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
The member variable _usart is directly initialized in the constructor, before any statement is executed.
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
Provide the USART object on the stack, as the logger.
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
The singleton design pattern is deprecated since it was invented, because it is so hard to test. Simply use just one object or a limiting object factory.

Why multithreading in c++ DLL get error C3867 when building?

I am using VS2019
Trying to call a thread in DLL. to run two executables simultaneously with detach
following threads worked when I Run a normal c++ program
I get error
Error C3867 'myClass::runexeone': non-standard syntax; use '&' to create a pointer to member myGateway C:\Users\user\Downloads\Demo\myGateway\myplugin.cpp 21
plugin header
#include <windows.h>
#include <iostream>
#include <thread>
#define MYPLUGIN_EXPORT __declspec(dllexport)
extern "C"
{
MYPLUGIN_EXPORT void WINAPI OnStart();
}
pluging.cpp
#include "plugin.h"
using namespace std;
class myClass
{
public:
myClass()
{
}
~myClass()
{
}
void onStart()
{
std::thread(runexeone).detach();
std::thread(runexetwo).detach();
}
void runexeone()
{
int exerunpne = system("cmd /C \"%MY_ROOT%\\bin\\Mytest.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
void runexetwo()
{
int exeruntwo = system("cmd /C \"%MY_ROOT%\\bin\\Mytest_2.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
};
myClass& getmyclass()
{
static myClass myclass;
return myclass;
}
MYPLUGIN_EXPORT void WINAPI OnStart()
{
getmyClass().onStart();
}
The problem is that runexeone is an unqualified name of a member function, and std::thread needs something executable. runexeone isn't. VC++ tries to guess from context what you mean, but the suggestion isn't enough. Even if you had written &myClass::runexeone, it still wouldn't have worked, because myClass::runexeone also needs a this pointer. You can fix the latter problem by making it static.
Compiler suggestions work best when there's just one problem.
As MSalters already mentioned, you provided the wrong data type for the functor for std::thread. If you cannot make the method static (which you can actually at least for the current state of your code, but to let this not be unstated here), you can do this
void onStart()
{
std::thread(std::bind(&myClass::runexeone, this)).detach();
}
But be careful about the lifetime/existence of your object/this!

Create a new thread using C in Qt4.8

I'm developing a simple instant-messaging software on Ubuntu 12.10, it's client requires GUI.
In the main window of the client, i need to create a thread to keep listening messages received from the server.
Here is the error message:
main.cpp:-1: In function 'int main(int, char**)':
main.cpp:27: error: invalid conversion from 'void*' to 'void* (*)(void*)' [-fpermissive]
/usr/include/pthread.h:225: error: initializing argument 3 of 'int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)' [-fpermissive]
In the maininterface.h:
Class MainInterface: public QWidget
{
public:
explicit MainInterface(QWidget *parent = 0);
~MainInterface();
void* ServerMSGWatch(void *threadArgs=NULL); // function run in the new thread
};
It's definition in maininterface.cpp is:
void* MainInterface::ServerMSGWatch(void *threadArgs)
{
pthread_detach(pthread_self());
char arrServerMSGRecv[SERVER_MSG_MAX_SIZE + 1];
while(1){
recv(Login::sockClnt, arrServerMSGRecv, SERVER_MSG_MAX_SIZE+1, 0);
Handle_Server_MSG(arrServerMSGRecv);
memset(arrServerMSGRecv, 0, SERVER_MSG_MAX_SIZE+1);
}
return NULL;
}
in main.cpp:
MainInterface mWindow;
mWindow.show();
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, mWindow.ServerMSGWatch(), NULL);
and in this question, i figured out that maybe there's something wrong with using a C++ compiler to compile c code.
so i tried to add a 'c_pthread.h':
#ifndef C_PTHREAD_H
#define C_PTHREAD_H
#ifdef __cplusplus
extern "C" {
#endif
void* ServerMSGWatch(void *threadArgs=NULL);
void Handle_Server_MSG(char *arrServerMSGRecv);
#ifdef __cplusplus
}
#endif
#endif // C_PTHREAD_H
and c_pthread.cpp:
void* ServerMSGWatch(void *threadArgs=NULL)
{
//definition
}
void Handle_Server_MSG(char *arrServerMSGRecv)
{
//definition
}
then invoke it in main.cpp:
#include "c_pthread.h"
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, ServerMSGWatch(), NULL);
but i still got the same error.
PS: sorry about some malapropisms.
You have two problems: The first is that you call the function instead of passing it. The other is more subtle, and is that you can't use a non-static class member function as a thread function.
The reason for the last problem is because non-static member function have a hidden first argument that is the this pointer.
In this case you can solve it by adding a static member function, and pass a pointer to the object as argument to the thread function. Then the static function calls the actual function in the object:
class MainInterface: public QWidget
{
public:
...
static void* StaticServerMSGWatch(void* arg)
{
reinterpret_cast<MainInterface*>(arg)->ServerMSGWatch();
return nullptr;
}
void ServerMSGWatch(); // function run in the new thread
};
...
pthread_create(&pthreadID, NULL, &MainInterface::StaticServerMSGWatch, &mWindow);
If you have a C++11 capable compiler and library, you could use std::thread instead:
std::thread myThread(&MainInterface::ServerMSGWatch, &mWindow);
As you see, you no longer need the static member function.
You're using Qt, so I strongly suggest using QThread. This will guarantee compatibility and the interop with the rest of your program will be better.
That being said, you need to pass a function pointer to pthread_create, and a member function pointer is not a function pointer: either make it static or make it a freestanding function.
In C++11, there's no need to muck around with low-level system libraries:
std::thread thread([&]{mWindow.ServerMSGWatch();});
If you're stuck with a historic version of C++ then, since you say you're using Qt, you might consider its thread class QThread.
If you're stuck with pthreads then, being a C API, it knows nothing about member functions, so you'll need a non-member, or static member function. (Strictly speaking, you should only use a non-member function declared extern "C", but in practice C++ functions will work on any sensible implementation).
So you'll need a wrapper function to call the member function:
void * CallServerMSGWatch(void * p) {
return static_cast<MainInterface*>(p)->ServerMSGWatch();
}
and tell pthread_create to pass a suitable pointer through to this:
pthread_create(&pthreadID, NULL, CallServerMSGWatch, &mWindow);
mWindow.ServerMSGWatch() is a function call.
mWindow.ServerMSGWatch is a function pointer.

pthread_create argument passing error

Trying to write some simple multithreaded server program and got that error recently:
Server.cpp:64:64: error: argument of type ‘void* (Server::)(void*)’ does not match ‘void* (*)(void*)
Here is some lines from my code:
Header file:
class Server
{
public:
void establishConnection(const char * );
...
private:
void *listening(void *);
void *acceptingConnection(void *);
pthread_attr_t attrr;
}
cpp file:
void Server:: establishConnection(const char *port_number )
{
...
pthread_create(&listn, &attrr, Server::listening, (void*)socketfd);//pthread_t listn, socketfd is a socket destricptor(int)
pthread_join(listn, NULL);
}
void* Server::listening(void *arg)
{
int socketfd = (int)arg;
...
}
Normally, if I define thread function prototypes in the cpp file instead of header file, it works properly(without Server:: definition of course) Tried few other things like (void*)Server::listening, listening, (void*)listening but still didnt work. Could you enlighten me? How to pass the method parameter to listening method?
Secondly, I am learning c++ currently(already know C), is it true to use some C methods, char* arrays instead of strings, header files in the c++ program? Such as string.h, stdlib.h, pthread.h?
You need to create a wrapper function for pthread_create(), and from there call into your class method.
class Server
{
...
private:
int sock;
};
extern "C" void * server_listening (void *arg) {
Server *s = static_cast<Server *>(arg);
return s->listening();
}
void Server:: establishConnection(const char *port_number )
{
...
this->sock = socketfd;
pthread_create(&listn, &attrr, server_listening, this);
pthread_join(listn, NULL);
}
The extern "C" linkage on the wrapper function is in place since pthread_create() is a C function, and expects a function pointer with C linkage. This is important if on your system the C ABI and the C++ ABI are not the same. A static method of a class can only have C++ linkage.
You can just read the error message:
type ‘void* (Server::)(void*)’ does not match ‘void* (*)(void*)‘
Because Server::listening is a non-static member function of Server, and a pointer non-static member function cannot possibly be converted to a pointer-to-non-member-function.
You have to make your Server::listening function static, or write a stand-alone function outside the Server class.

No matching function call to 'pthread_create'

I'm using Xcode and C++ to make a simple game.
The problem is the following code:
#include <pthread.h>
void *draw(void *pt) {
// ...
}
void *input(void *pt) {
// ....
}
void Game::create_threads(void) {
pthread_t draw_t, input_t;
pthread_create(&draw_t, NULL, &Game::draw, NULL); // Error
pthread_create(&input_t, NULL, &Game::draw, NULL); // Error
// ...
}
But Xcode gives me the error: "No matching function call to 'pthread_create'". I haven't an idea 'cause of I've included pthread.h already.
What's wrong?
Thanks!
As Ken states, the function passed as the thread callback must be a (void*)(*)(void*) type function.
You can still include this function as a class function, but it must be declared static. You'll need a different one for each thread type (e.g. draw), potentially.
For example:
class Game {
protected:
void draw(void);
static void* game_draw_thread_callback(void*);
};
// and in your .cpp file...
void Game::create_threads(void) {
// pass the Game instance as the thread callback's user data
pthread_create(&draw_t, NULL, Game::game_draw_thread_callback, this);
}
static void* Game::game_draw_thread_callback(void *game_ptr) {
// I'm a C programmer, sorry for the C cast.
Game * game = (Game*)game_ptr;
// run the method that does the actual drawing,
// but now, you're in a thread!
game->draw();
}
compilation of threads using pthread is done by providing options -pthread.
Such as compiling abc.cpp would require you to compile like g++ -pthread abc.cpp else would
give you an error like undefined reference topthread_create collect2: ld returned 1 exit status` . There must be some similar way to provide pthread option.
You're passing a member function pointer (i.e. &Game::draw) where a pure function pointer is required. You need to make the function a class static function.
Edited to add: if you need to invoke member functions (which is likely) you need to make a class static function which interprets its parameter as a Game* and then invoke member functions on that. Then, pass this as the last parameter of pthread_create().