I have a class in C++ that uses boost python. I am trying to run python code in a thread from C++ using pthread. The problem is that the code below isn't producing any output. I was expecting an output John DOE in stdout. It seems that &this->instance doesn't carry the values that are being set inside the object. How can I pass current object or its instance variable to the pthread_create so that pthread can see what is being passed?
Python:
class A:
def __init__(self, name):
self.name = name
def printName(self, lastName):
print self.name + " " + lastName
C++:
#include <boost/python.hpp>
#include <string.h>
#include <pthread.h>
using namespace std;
using namespace boost::python;
class B {
public:
object instance;
B();
void setupPython();
static void *runPython(void *);
};
B::B() {
Py_Initialize();
}
void B::setupPython() {
pthread_t t1;
try {
object a = import("A");
instance = a.attr("A")("John");
pthread_create(&t1, NULL, runPython, &this->instance); // THIS IS PROBLEM
}
catch(error_already_set const &) {
PyErr_Print();
}
}
void *B::runPython(void *instance) {
((object *)instance)->attr("printName")("DOE");
}
int main() {
B b;
b.setupPython();
}
Thank you.
The problem is:
int main() {
B b;
b.setupPython(); // You create a thread here
// But here, b is destroyed when it's scope ends
}
The code in your thread is not guaranteed to run before b is freed.
Try allocating b on the heap and check if it works:
int main() {
B* b = new B();
b->setupPython();
// also, you should add a call to pthread_join
// here to wait for your thread to finish execution.
// For example, changing setupPython() to return the
// pthread_t handle it creates, and calling pthread_join on it.
}
Related
I am calling a member function inside the thread. I have a member variable that I edit inside this function for which I have applied the lock.
Is this logic okay or do even the reads need to be thread-safe?
The code is something like the one shown below:
#include <iostream>
#include <vector>
#include <mutex>
#include <future>
#include <memory>
using namespace std;
class A
{
int occurrence;
mutex m;
public:
A() = default;
void operation()
{
/*--
Some operations where I only read the class members other than occurrence but do not modify them.
--*/
{
lock_guard<mutex> my_lock(m);
occurence++;
}
}
int getOccurence()
{
return occurence;
}
};
class B
{
shared_ptr<A> a{};
public:
B(shared_ptr<A>& a_ptr)
{
a = a_ptr;
}
void callAoperation()
{
a->operation();
}
};
int main()
{
shared_ptr<A> a = make_shared<A>();
B* b = new B(a);
vector<std::future<void>> async_call;
int i = 0;
while (i < 10)
{
async_call.push_back(async(launch::async, &B::callAoperation, b));
i++;
}
for (auto&& fut : async_call)
{
fut.wait();
}
cout << a->getOccurence();
}
Inside my operation method, I modify only one variable, others I just read.
The class variable which I am modifying is inside a lock.
I want to know, Is this logic correct or will it have some issues?
The logic is not correct. While reading a variable, another thread can modify it, leading the data race. You should use std::shared_mutex and protect reading from writing using std::shared_lock, prevent writing while reading with std::unique_lock.
I need help with passing a function pointer on C++. I can't linkage one function for a class to other function. I will explain. Anyway I will put a code resume of my program, it is much larger than the code expose here but for more easier I put only the part I need to it works fine.
I have one class (MainSystem) and inside I have an object pointer to the other class (ComCamera). The last class is a SocketServer, and I want when the socket received any data, it sends to the linkage function to MainSystem.
ComCamera is a resource Shared with more class and I need to associate the functions ComCamera::vRecvData to a MainSystem::vRecvData or other function of other class for the call when receive data and send de data to the function class associate.
Can Anyone help to me?
EDDITED - SOLUTION BELOW
main.cpp
#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#include <exception>
#include <unistd.h>
using std::string;
class ComCamera {
public:
std::function<void(int, std::string)> vRecvData;
void vLinkRecvFunction(std::function<void(int, std::string)> vCallBack) {
this->vRecvData = vCallBack;
}
void vCallFromCamera() {
this->vRecvData(4, "Example");
};
};
class MainSystem {
private:
ComCamera *xComCamera;
public:
MainSystem(ComCamera *xComCamera) {
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iChannelNumber, std::string sData) {vRecvData(iChannelNumber, sData); });
}
void vRecvData(int iNumber, string sData) {
std::cout << "RECV Data From Camera(" + std::to_string(iNumber) + "): " << sData << std::endl;
};
};
int main(void) {
ComCamera xComCamera;
MainSystem xMainSystem(&xComCamera);
xComCamera.vCallFromCamera();
return 0;
}
Output will be:
MainSystem RECV Data From Camera(4): Example
You can have ComCamera::vRecvData be of type std::function<void(int, std::string)> and then have ComCamera::vLinkRecvFunction() be like this:
void ComCamera::vLinkRecvFunction(std::function<void(int, std::string)> callBack)
{
this->vRecvData = callBack;
}
and have MainSystem constructor be like this:
MainSystem::MainSystem(ComCamera *xComCamera)
{
using namespace std::placeholders;
this->xComCamera = xComCamera;
this->xComCamera->vLinkRecvFunction([this](int iNumber, std::string sData){vRecvData(number, sData);});
}
Still though the original question has way too much code to go through friend.
Here what you want :
#include<iostream>
using std::cout;
class A; //forward declare A
class B{
public:
void (A::*ptr)(int x); //Only declare the pointer because A is not yet defined.
};
class A{
public:
void increase_by(int x){
a+=x;
} // this function will be pointed by B's ptr
int a = 0; // assume some data in a;
B b; // creating B inside of A;
void analyze(int y){
(*this.*(b.ptr))(y);
} // Some function that analyzes the data of A or B; Here this just increments A::a through B's ptr
};
int main(){
A a; // creates A
cout<<a.a<<"\n"; // shows initial value of a
a.b.ptr = &A::increase_by; // defines the ptr that lies inside of b which inturns lies inside a
a.analyze(3); // calls the initialize method
(a.*(a.b.ptr))(3); // directly calls b.ptr to change a.a
cout<<a.a; // shows the value after analyzing
return 0;
}
Output will be :
0
6
I still don't get why would you do something like this. But maybe this is what you wanted as per your comments.
To know more read this wonderful PDF.
I have the follwing code that gets core dumped error. Each C instance creates their own thread then runs. I guess there is something wrong with static function and class argument "count". When I comment out the code that prints it, no fault occurs..
#include <iostream>
#include <pthread.h>
using namespace std;
class C {
public:
int count;
C(int c_): count(c_){}
public:
void *hello(void)
{
std::cout << "Hello, world!" <<std::endl;
std::cout<<count; // bug here!!!
return 0;
}
static void *hello_helper(void *context)
{
return ((C *)context)->hello();
}
void run() {
pthread_t t;
pthread_create(&t, NULL, &C::hello_helper, NULL);
}
};
int main() {
C c(2);
c.run();
C c2(4);
c2.run();
while(true);
return 0;
}
Decided to write an answer. You were calling hello_helper with a context of NULL based on how you were creating your thread. C++ fully allows you to call member functions on null pointers, and no error occurs unless a member element is accessed.
In your case, by adding the line to print count. You are now accessing a member variable on a null pointer, which is a big no-no.
Here's an example of what you were getting away with:
#include <iostream>
class Rebel
{
public:
void speak()
{
std::cout << "I DO WHAT I WANT!" << std::endl;
}
};
int main()
{
void * bad_bad_ptr = NULL;
((Rebel*)bad_bad_ptr)->speak();
}
Output:
I DO WHAT I WANT!
By modifying your pthread_create call to pass the this pointer (i.e. pthread_create(&t, NULL, &C::hello_helper, this);, you now have a valid instance to access member variables on.
I solved the problem by passing this pointer instead off NULL while creating threads. I guess os created same thread twice int the former case ?
I have a C++ class that I want to give access to in the lua script through a global variable, however when I try to use it I get the following error:
terminate called after throwing an instance of 'luabind::error'
what(): lua runtime error
baz.lua:3: attempt to index global 'foo' (a nil value)Aborted (core dumped)
My Lua script (baz.lua) looks like this:
-- baz.lua
frames = 0
bar = foo:createBar()
function baz()
frames = frames + 1
bar:setText("frame: " .. frames)
end
And I'm made a simple and short (as well as I could) main.cpp that recreates this problem:
#include <memory>
#include <iostream>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <boost/ref.hpp>
#include <luabind/luabind.hpp>
class bar
{
public:
static void init(lua_State *L)
{
using luabind::module;
using luabind::class_;
module(L)
[
class_<bar>("bar")
.def("setText", &bar::setText)
];
}
void setText(const std::string &text)
{
std::cout << text << std::endl;
}
};
class foo
{
public:
foo() :
L(luaL_newstate())
{
int ret = luaL_dofile(L, "baz.lua");
if (ret != 0) {
std::cout << lua_tostring(L, -1);
}
luabind::open(L);
using luabind::module;
using luabind::class_;
module(L)
[
class_<foo>("bar")
.def("createBar", &foo::createBar)
];
bar::init(L);
luabind::globals(L)["foo"] = boost::ref(*this);
}
boost::reference_wrapper<bar> createBar()
{
auto b = std::make_shared<bar>();
bars_.push_back(b);
return boost::ref(*b.get());
}
void baz()
{
luabind::call_function<void>(L, "baz");
}
private:
lua_State *L;
std::vector<std::shared_ptr<bar>> bars_;
};
int main()
{
foo f;
while (true) {
f.baz();
}
}
This is compiled with:
g++ -std=c++11 -llua -lluabind main.cpp
I've discovered that if I put the bar = foo:createBar() into the baz() function then it doesn't error, so I assume I'm not initialising the globals in the global namespace correctly? Am I missing a luabind function that I need to call before I am able to do this? Or is this just not possible at all...
Thanks!
You're running baz.lua before you register any globals. Put the dofile command after registering your bindings.
The sequence is as follows:
You invoke foo's constructor in C++, which
creates a Lua state
runs lua.baz
registers your bindings
then in c++ you call f.baz.
I am trying to call the function hello which belongs to the class program1
#include <iostream>
using namespace std;
class program1
{
program1();
~program1();
hello();
}
program1::hello()
{
cout<<"hello";
}
int main()
{
program1.hello(); //Call it like a normal function...
cin.get();
}
Names inside a class are private by default.
class program1 {
public:
program1();
~program1();
void hello() ;
};
// ...
int main(int, char **) {
program1 myProgram;
myProgram.hello();
return 0;
}
Alternatively, you can invoke a method on a temporary:
int main(int, char **) {
program1().hello();
return 0;
}
but that's probably for later in the semester.
you forgot to create an object:
int main()
{
program1 p1;
p1.hello();
}
Class definition should end with ;
Secondly, you need to instantiate class to call members on it. ( i.e., creation of an object for the class )
In C++, methods should have return type.
program1::hello(); // method should have a return type.
class members and methods are private by default, which means you cannot access them outside the class-scope.
So, the class definition should be -
class program1
{
public: // Correction 1
program1();
~program1();
void hello(); // Correction 2
};
void program1::hello() // Need to place return type here too.
{
cout<<"hello";
}
Now on creation of object for class program1, it's method hello() can be called on it.
This version is edited. (make sure you include all the body of the methods)
#include <iostream>
using namespace std;
class program1
{
public: // To allow outer access
program1();
~program1();
void hello(); // The void
}; // Don't miss this semicolon
void program1::hello() // The void
{
cout<<"hello";
}
int main()
{
program1 prog; // Declare an obj
prog.hello(); //Call it like a normal function...
cin.get();
}
I noticed that you left out return type for your hello() function.
If you want to call hello() as a member function, then as suggested you should create an object to it.
program1 prog;
prog.hello();
If you want to call it without an object, the you should use static function.
class program1
{
public: // To allow outer access
program1();
~program1();
static void hello(); // The void
}
then you can call it this way:
program1::hello();
Therefore the working code should be this way:
#include <iostream>
using namespace std;
class program1 {
public:
void hello();
}; // Don't miss this semicolon
class program2 {
public:
void static hello(); // to demonstrate static function
}; // Don't miss this semicolon
void program1::hello() {
cout << "Hello, I'm program1." << endl;
}
void program2::hello() {
cout << "Hello, I'm program2." << endl;
}
int main(void) {
program1 prog1;
prog1.hello(); // Non-static function requires object
program2::hello(); // Static function doesn't
return 0; // Return 0
}