SDL Multithreading with variables -- Doesn't work as expected [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have in a namespace called Main an static integer, and a static class variable called other, like this:
namespace Main {
void test();
static Client other;
static int v = 0;
}
Then, when the program starts, Main::test() is called, and creates a thread via SDL:
void test() {
SDL_CreateThread(Client::test, (const char*)"Client", (void*)NULL);
v = 1;
std::cout << v << std::endl;
...
}
This makes the Client start a function called test, which prints the vector size forever, like so:
int Client::test(void* data)
{
while(1) {std::cout << Main::v << std::endl; }
}
Now, here's the problem! Main returns 1 and Client returns a lot of zeros! What happened there? The variable is static, so it should be the same for Client!

std::vector.size() is, by definition, the number of elements in the vector.
Any situation where you think that isn't the case, or you see symptoms of that not being the case, you are probably experiencing undefined behavior due to memory corruption or out-of-bounds accesses.
Note that assigning to an indexed location of a vector v[n] = x; does not extend the vector, and is undefined behavior if n >= v.size().

Without explicit synchronization, the compiler is allowed to optimize the Client::test method by assuming that v never changes.
This is because it obviously doesn't change in that thread, it's your responsibility to tell the compiler if it could change in a different thread, and you did no such thing.

You are using a standard container in two threads, so you need to protect every access with a mutex. That creates a memory fence (which solves the problem you've seen), and protects from internal corruption when you perform actions on the container from different threads simultaneously (which your answer does not attempt to solve).

Related

How Can this == nullptr Ever be true Without Invoking Undefined Behavior? [duplicate]

Does it ever make sense to check if this is null?
Say I have a class with a method; inside that method, I check this == NULL, and if it is, return an error code.
If this is null, then that means the object is deleted. Is the method even able to return anything?
Update: I forgot to mention that the method can be called from multiple threads and it may cause the object to be deleted while another thread is inside the method.
Does it ever make sense to check for this==null? I found this while doing a code review.
In standard C++, it does not, because any call on a null pointer is already undefined behavior, so any code relying on such checks is non-standard (there's no guarantee that the check will even be executed).
Note that this holds true for non-virtual functions as well.
Some implementations permit this==0, however, and consequently libraries written specifically for those implementations will sometimes use it as a hack. A good example of such a pair is VC++ and MFC - I don't recall the exact code, but I distinctly remember seeing if (this == NULL) checks in MFC source code somewhere.
It may also be there as a debugging aid, because at some point in the past this code was hit with this==0 because of a mistake in the caller, so a check was inserted to catch future instances of that. An assert would make more sense for such things, though.
If this == null then that means the object is deleted.
No, it doesn't mean that. It means that a method was called on a null pointer, or on a reference obtained from a null pointer (though obtaining such a reference is already U.B.). This has nothing to do with delete, and does not require any objects of this type to have ever existed.
Your note about threads is worrisome. I'm pretty sure you have a race condition that can lead to a crash. If a thread deletes an object and zeros the pointer, another thread could make a call through that pointer between those two operations, leading to this being non-null and also not valid, resulting in a crash. Similarly, if a thread calls a method while another thread is in the middle of creating the object, you may also get a crash.
Short answer, you really need to use a mutex or something to synchonize access to this variable. You need to ensure that this is never null or you're going to have problems.
I know that this is old but I feel like now that we're dealing with C++11-17 somebody should mention lambdas. If you capture this into a lambda that is going to be called asynchronously at a later point in time, it is possible that your "this" object gets destroyed before that lambda is invoked.
i.e passing it as a callback to some time-expensive function that is run from a separate thread or just asynchronously in general
EDIT: Just to be clear, the question was "Does it ever make sense to check if this is null" I am merely offering a scenario where it does make sense that might become more prevalent with the wider use of modern C++.
Contrived example:
This code is completely runable. To see unsafe behavior just comment out the call to safe behavior and uncomment the unsafe behavior call.
#include <memory>
#include <functional>
#include <iostream>
#include <future>
class SomeAPI
{
public:
SomeAPI() = default;
void DoWork(std::function<void(int)> cb)
{
DoAsync(cb);
}
private:
void DoAsync(std::function<void(int)> cb)
{
std::cout << "SomeAPI about to do async work\n";
m_future = std::async(std::launch::async, [](auto cb)
{
std::cout << "Async thread sleeping 10 seconds (Doing work).\n";
std::this_thread::sleep_for(std::chrono::seconds{ 10 });
// Do a bunch of work and set a status indicating success or failure.
// Assume 0 is success.
int status = 0;
std::cout << "Executing callback.\n";
cb(status);
std::cout << "Callback Executed.\n";
}, cb);
};
std::future<void> m_future;
};
class SomeOtherClass
{
public:
void SetSuccess(int success) { m_success = success; }
private:
bool m_success = false;
};
class SomeClass : public std::enable_shared_from_this<SomeClass>
{
public:
SomeClass(SomeAPI* api)
: m_api(api)
{
}
void DoWorkUnsafe()
{
std::cout << "DoWorkUnsafe about to pass callback to async executer.\n";
// Call DoWork on the API.
// DoWork takes some time.
// When DoWork is finished, it calls the callback that we sent in.
m_api->DoWork([this](int status)
{
// Undefined behavior
m_value = 17;
// Crash
m_data->SetSuccess(true);
ReportSuccess();
});
}
void DoWorkSafe()
{
// Create a weak point from a shared pointer to this.
std::weak_ptr<SomeClass> this_ = shared_from_this();
std::cout << "DoWorkSafe about to pass callback to async executer.\n";
// Capture the weak pointer.
m_api->DoWork([this_](int status)
{
// Test the weak pointer.
if (auto sp = this_.lock())
{
std::cout << "Async work finished.\n";
// If its good, then we are still alive and safe to execute on this.
sp->m_value = 17;
sp->m_data->SetSuccess(true);
sp->ReportSuccess();
}
});
}
private:
void ReportSuccess()
{
// Tell everyone who cares that a thing has succeeded.
};
SomeAPI* m_api;
std::shared_ptr<SomeOtherClass> m_data = std::shared_ptr<SomeOtherClass>();
int m_value;
};
int main()
{
std::shared_ptr<SomeAPI> api = std::make_shared<SomeAPI>();
std::shared_ptr<SomeClass> someClass = std::make_shared<SomeClass>(api.get());
someClass->DoWorkSafe();
// Comment out the above line and uncomment the below line
// to see the unsafe behavior.
//someClass->DoWorkUnsafe();
std::cout << "Deleting someClass\n";
someClass.reset();
std::cout << "Main thread sleeping for 20 seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds{ 20 });
return 0;
}
FWIW, I have used debugging checks for (this != NULL) in assertions before which have helped catch defective code. Not that the code would have necessarily gotten too far with out a crash, but on small embedded systems that don't have memory protection, the assertions actually helped.
On systems with memory protection, the OS will generally hit an access violation if called with a NULL this pointer, so there's less value in asserting this != NULL. However, see Pavel's comment for why it's not necessarily worthless on even protected systems.
Your method will most likely (may vary between compilers) be able to run and also be able to return a value. As long as it does not access any instance variables. If it tries this it will crash.
As others pointed out you can not use this test to see if an object has been deleted. Even if you could, it would not work, because the object may be deleted by another thread just after the test but before you execute the next line after the test. Use Thread synchronization instead.
If this is null there is a bug in your program, most likely in the design of your program.
I'd also add that it's usually better to avoid null or NULL. I think the standard is changing yet again here but for now 0 is really what you want to check for to be absolutely sure you're getting what you want.
This is just a pointer passed as the first argument to a function (which is exactly what makes it a method). So long as you're not talking about virtual methods and/or virtual inheritance, then yes, you can find yourself executing an instance method, with a null instance. As others said, you almost certainly won't get very far with that execution before problems arise, but robust coding should probably check for that situation, with an assert. At least, it makes sense when you suspect it could be occuring for some reason, but need to track down exactly which class / call stack it's occurring in.
I know this is a old question, however I thought I will share my experience with use of Lambda capture
#include <iostream>
#include <memory>
using std::unique_ptr;
using std::make_unique;
using std::cout;
using std::endl;
class foo {
public:
foo(int no) : no_(no) {
}
template <typename Lambda>
void lambda_func(Lambda&& l) {
cout << "No is " << no_ << endl;
l();
}
private:
int no_;
};
int main() {
auto f = std::make_unique<foo>(10);
f->lambda_func([f = std::move(f)] () mutable {
cout << "lambda ==> " << endl;
cout << "lambda <== " << endl;
});
return 0;
}
This code segment faults
$ g++ -std=c++14 uniqueptr.cpp
$ ./a.out
Segmentation fault (core dumped)
If I remove the std::cout statement from lambda_func The code runs to completion.
It seems like, this statement f->lambda_func([f = std::move(f)] () mutable { processes lambda captures before member function is invoked.

Confusion about thread-safety

I am new to the world of concurrency but from what I have read I understand the program below to be undefined in its execution. If I understand correctly this is not threadsafe as I am concurrently reading/writing both the shared_ptr and the counter variable in non-atomic ways.
#include <string>
#include <memory>
#include <thread>
#include <chrono>
#include <iostream>
struct Inner {
Inner() {
t_ = std::thread([this]() {
counter_ = 0;
running_ = true;
while (running_) {
counter_++;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
});
}
~Inner() {
running_ = false;
if (t_.joinable()) {
t_.join();
}
}
std::uint64_t counter_;
std::thread t_;
bool running_;
};
struct Middle {
Middle() {
data_.reset(new Inner);
t_ = std::thread([this]() {
running_ = true;
while (running_) {
data_.reset(new Inner());
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
});
}
~Middle() {
running_ = false;
if (t_.joinable()) {
t_.join();
}
}
std::uint64_t inner_data() {
return data_->counter_;
}
std::shared_ptr<Inner> data_;
std::thread t_;
bool running_;
};
struct Outer {
std::uint64_t data() {
return middle_.inner_data();
}
Middle middle_;
};
int main() {
Outer o;
while (true) {
std::cout << "Data: " << o.data() << std::endl;
}
return 0;
}
My confusion comes from this:
Is the access to data_->counter safe in Middle::inner_data?
If thread A has a member shared_ptr<T> sp and decides to update it while thread B does shared_ptr<T> sp = A::sp will the copy and destruction be threadsafe? Or do I risk the copy failing because the object is in the process of being destroyed.
Under what circumstances (can I check this with some tool?) is undefined likely to mean std::terminate? I suspect something like the above happens in some of my production code but I cannot be certain as I am confused about 1 and 2 but this small program has been running for days since I wrote it and nothing happens.
Code can be checked here at https://godbolt.org/g/saHz94
Is the access to data_->counter safe in Middle::inner_data?
No; it's a race condition. According to the standard, it's undefined behavior anytime you allow unsynchronized access to the same variable from more than one thread, and at least one thread might possibly modify the variable.
As a practical matter, here are a couple of unwanted behaviors you might see:
The thread reading the value of counter_ reads an "old" value of counter (that rarely or never updates) due to different processor cores caching the variable independently of each other (using atomic_t would avoid this problem, because then the compiler would be aware that you are intending this variable to be accessed in an unsynchronized manner, and it would know to take precautions to prevent this problem)
Thread A might read the address that the data_ shared_pointer points to and be just about to dereference the address and read from the Inner struct it points to, when Thread A gets kicked off the CPU by thread B. Thread B executes, and during Thread B's execution, the old Inner struct gets deleted and the data_ shared_pointer set to point to a new Inner struct. Then Thread A gets back onto the CPU again, but since Thread A already has the old pointer value in memory, it dereferences the old value rather than the new one and ends up reading from freed/invalid memory. Again, this is undefined behavior, so in principle anything could happen; in practice you're likely to see either no obvious misbehavior, or occasionally a wrong/garbage value, or possibly a crash, it depends.
If thread A has a member shared_ptr sp and decides to update it
while thread B does shared_ptr sp = A::sp will the copy and
destruction be threadsafe? Or do I risk the copy failing because the
object is in the process of being destroyed.
If you're only retargeting the shared_ptrs themselves (i.e. changing them to point to different objects) and not modifying the T objects that they point to, that should be thread safe AFAIK. But if you are modifying state of the T objects themselves (i.e. the Inner object in your example) that is not thread safe, since you could have one thread reading from the object while another thread is writing to it (deleting the object can be seen as a special case of writing to it, in that it definitely changes the object's state)
Under what circumstances (can I check this with some tool?) is
undefined likely to mean std::terminate?
When you hit undefined behavior, it's very much dependent on the details of your program, the compiler, the OS, and the hardware architecture what will happen. In principle, undefined behavior means anything (including the program running just as you intended!) can happen, but you can't rely on any particular behavior -- which is what makes undefined behavior so evil.
In particular, it's common for a multithreaded program with a race condition to run fine for hours/days/weeks and then one day the timing is just right and it crashes or computes an incorrect result. Race conditions can be really difficult to reproduce for that reason.
As for when terminate() might be called, terminate() would be called if the the fault causes an error state that is detected by the runtime environment (i.e. it corrupts a data structure that the runtime environment does integrity checks on, such as, in some implementations, the heap's metadata). Whether or not that actually happens depends on how the heap was implemented (which varies from one OS and compiler to the next) and what sort of corruption the fault introduced.
Thread safety is an operation between threads, not an absolute in general.
You cannot read or write a variable while another thread writes a variable without synchronization between the other thread's write and your read or write. Doing so is undefined behavior.
Undefined can mean anything. Program crashes. Program reads impossible value. Program formats hard drive. Program emails your browser history to all of your contacts.
A common case for unsynchronized integer access is that the compiler optimizes multiple reads to a value into one and doesn't reload it, because it can prove there is no defined way that someone could have modified the value. Or, the CPU memory cache does the same thing, because you did not synchronize.
For the pointers, similar or worse problems can occur, including following dangling pointers, corrupting memory, crashes, etc.
There are now atomic operations you can perform on shared pointers., as well as atomic<shared_ptr<?>>.

std::thread throws Access violation exception when created with arguments? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm using VS2015 and encounter a extremely strange problem when using std::thread.
void Klass::myfunc(int a, int b) { std::cout << a << ' ' << b << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc, this, 100, 200); <- runtime error after called
// ...
t.join();
It works well on Debug mode, but throws an "Access violation exception" when I turn to Release mode.
What's more, if I try to modify "myfunc" to this:
void Klass::myfunc() { std::cout << "foo" << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc, this); // everything goes well
// ...
t.join();
it works well again.
I'm guarantee that "&Klass::myfunc" and "this" pointers are not NULL. And there is a "join" after several lines when the ctor is called.
I guess it might be some kind of "undefined behavior" but I have no idea what is it exactly.
The call stack is something like this:
000000c83a4ffd40() Unknown
> distributed_word_embedding.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64> > > >::_Run(std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *> > > > * _Ln) Line 247 C++
distributed_word_embedding.exe!std::_Pad::_Call_func(void * _Data) Line 210 C++
ucrtbase.dll!00007ffabdc7be1d() Unknown
kernel32.dll!00007ffabfae8102() Unknown
ntdll.dll!00007ffac26bc5b4() Unknown
You should always make sure you join (or possibly detach) a thread, otherwise leaving main especially with a thread using objects (in this case this) will (sometimes) cause problems.
//... details omitted...
int main()
{
auto t = std::thread(&Klass::myfunc, this);
t.join(); //<----- NOTE THIS
}
Anthony William's threading blog goes through this in detail. With an example very similar to your second one:
void my_thread_func()
{
std::cout<<"hello"<<std::endl;
}
int main()
{
std::thread t(my_thread_func);
}
He says
If you compile and run this little application, what happens? Does it
print hello like we wanted? Well, actually there's no telling. It
might do or it might not. I ran this simple application several times
on my machine, and the output was unreliable: sometimes it output
"hello", with a newline; sometimes it output "hello" without a
newline, and sometimes it didn't output anything. What's up with that?
Surely a simple app like this ought to behave predictably?
He then introduces the idea of using join as I did above, and says,
The problem is we're not waiting for our thread to finish. When the
execution reaches the end of main() the program is terminated,
whatever the other threads are doing.

some problems about c++ try catch [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a question about try catch mechanism. like code:
global value default 0;
int thread1()
{
try
{
set global value to 1;
if exception happens
{
jump into catch;
}
set global value to 0;
}
catch
{
......
}
}
int thread2()
{
ASSERT(global value = 0);
}
If I have the fake code as shown, in try block I set a global value to 1 and then an exception happens, in thread2 I have a ASSERT to test if this global value is equal to 0, then thread2 will failed explicitly because in thread1, we jump into the catch block because of an exception. So can anybody give me some explanation ? I don't know how try--catch works to prevent this.
Exceptions are brutal break of the normal flow of execution. The error correcting flow is to find a catch that correspond to the object thrown; this may lead to several function calls reverse traversal. This is why it needs care to use them, you have two flow of execution : the normal one, and the error one.
If the exception thrown is catched by the catch-block directly after, then you just have to set your variable to 0 in the catch-block.
It not, a good solution is RAII (as suggested in comments). RAII is a very simple idea. As you know that every object created on stack at the entry of any block is destroyed when control leave the block, the idea is to build an object that encapsulate something, so that the destructor will be called whatever happens:
class GlobalControl {
public:
GlobalControl() { myglob = 1; } // RAII
~GlobalControl() { myglob = 0; } // RRID
};
... // somewhere else
try {
GlobalControl c; // ctor call init glob to 1
...
} // whatever will happens, leaving this block cause a call to dtor of c
catch (...) {
}
RAII stands for Resource Acquisition Is Initialization, here your resource acquisition is to set your global to 1, and this is made in the initialization part of the object. RAII should be called RAIIRRID, RAII + Resource Releasing Is Destruction (the resource release is to set your global to 0, and this is made in the destructor).

Multiple threads cannot access the same pointer without error [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I am making an application with GLFW3 (window library), and I my OS is Windows 8.1.
My error: I make a pointer in my main thread and the window's thread gets an access violation when it tries to use it.
In my application I am trying to make an input handler class that takes in events from the window and sends them to all objects that subscribe to the event.
To do this, I have all objects that want to listen inherit InputListener:
class InputListener{
public:
virtual void onKeyDown(int key) = 0;
};
To subscribe to an event, a object must use a pseudo-global (reference passed to classes on construction) wrapper variable which contains my InputHandler:
// My global wrapper
#include "InputHandler.h"
class Centrum{
public:
InputHandler inputHandler;
public:
Centrum(){}
};
InputHandler
class InputHandler{
private:
unsigned numEvents;
InputListener* key_down; // Only trying to test on one subscriber for now.
public:
InputHandler();
void registerKeyDown(InputListener* listener, int key);
void key_event(int key, int action); // Is indirectly called by glfw window (same thread though)
};
// Implementation
InputHandler::InputHandler(){
numEvents = 0;
}
void InputHandler::registerKeyDown(InputListener* listener, int key){
// This is called from my main thread
key_down = listener;
key_down->onKeyDown(key); // Properly calls function on my Camera class which inherits InputListener
numEvents++;
printf("yes %u\n", numEvents);
}
void InputHandler::key_event(int key, int action){
// This is called by the window's thread (glfw automatically makes this thread)
printf("failure %u\n", numEvents); // Properly prints out numEvents
key_down->onKeyDown(key); // Runtime error here, access violation
}
Example of subscribing to input:
Camera::Camera(Centrum& g_centrum){
this->g_centrum = g_centrum;
[...]
g_centrum.inputHandler.registerKeyDown(this, GLFW_KEY_W);
}
The variable being pointed to was dying before it could be used. So, when the thread tried to use it, it threw a runtime error.
In this line you are copying the Centrum:
this->g_centrum = g_centrum;
You then register with the copy (which makes the first call to onKeyDown which naturally works). But you haven't registered with the original Centrum, so it has no key_down to call, so when it attempts to do so, without checking if the pointer is valid, it fails.
I'd make g_centrum a pointer, and probably use pointers rather than references to Centrum throughout.
Threads have separate stacks, so objects can only be accessed by several thread if they are heap-allocated.
Furthermore you should protect against concurrent access to those objects (or at least to the concurrent data) via mutexes.
If Camera is instanciated in the windows thread, you will create a copy of centrum.
Camera::Camera(Centrum& g_centrum){
this->g_centrum = g_centrum;
[...]
g_centrum.inputHandler.registerKeyDown(this, GLFW_KEY_W);
}
You should instanciate your Centrumlike so Centrum *mycentrum = new Centrum() and pass it as a pointer to your Camera.