I am getting into threading in C++ and was going some testing and got this error.
Here is my code:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
void thread1() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
thisVector.push_back(to_string(i));
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
The weird thing is, sometimes I get the correct output, so 800. Sometimes I get a number slightly lower than that for I don't know what reason??? And sometimes I get the following error:
malloc: *** error for object 0x100400028: pointer being freed was not allocated
Any help would be greatly appreciated!
Thanks
A std::vector is not thread safe. You have two execution threads modifying the same std::vector concurrently. Operations on a std::vector should, in this case, be protected by a mutex.
The result of this is undefined behavior. As you've observed, sometimes it might work, sometimes wrong results get produced but the program completes successfully, sometimes the program crashes. This is what "undefined behavior" means.
It is worth reading The C++ Programming Language, it covers subjects of interest like : threads, tasks, but also at higher conceptual level future/promise, packaged_task, async.
In your case, you don't only deal with concurrency. You have to deal with shared data of concurrent threads. The way you programmed it does not guarantee any order of execution. That is why you get those strange results.
The error message you mentioned is likely to be because of concurrent access to the shared vector and it says what is wrong: a pointer is being freed (delete), but was not allocated beforehand. You don't see the pointer, it's an internal member of vector.
Your solution is to use a mutex to make sure that whenever a data is pushed back into the vector it does not get interrupted by the other concurrent thread and finishes appropriately, so that the next push_back starts only when the previous one has finished.
You can use a global variable for mutex. Then you need to deal appropriately with locking/unlocking, i.e. you must say when to acquire a mutex (before push_back) and when to release it (after push_back). Since you use only one mutex this should be fairly simple and should work.
You can try something like this:
#include <iostream>
#include <thread>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;
static vector<string> thisVector;
//Global MUTEX
mutex mv;
//
void thread1() {
for (int i = 0; i < 400; i++){
//Lock before and unlock after push back
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 1" << endl;
return;
}
void thread2() {
for (int i = 0; i < 400; i++){
mv.lock();
thisVector.push_back(to_string(i));
mv.unlock();
}
cout << "Finished 2" << endl;
return;
}
int main(int argc, const char * argv[]) {
thread first(thread1);
thread second(thread2);
first.join();
second.join();
cout << "done threading" << endl;
cout << thisVector.size() << endl;
return 0;
}
Related
I'm new to C++ and am trying to have two threads run:
i) Thread that keeps looping until an atomic bool is flipped.
ii) A thread that polls for input from keyboard and flips the atomic bool.
I seem to be unable to get std::cin.get() to react to an input unless it is assigned its' own thread (like below). Why? Would it not then be set from the parent main thread?
#include <iostream>
#include <iomanip> // To set decimal places.
#include <thread> //std::thread
#include <atomic> //for atomic boolean shared between threads.
#include <math.h>
#define USE_MATH_DEFINES //For PI
std::atomic<bool> keepRunning(false); //set to false to avoid compiler optimising away.
void loop(){
int t = 1;
while(!keepRunning.load(std::memory_order_acquire)) //lower cost than directly polling atomic bool?
{
//Write sine wave output to console.
std::cout << std::setprecision(3) << sin(M_PI * 2 * t/100) << std::endl;
(t<101)? t++ : t = 1;
}
}
//This works, as opposed to stopping in main.
void countSafe(){
int j = 1;
while (j<1E7)
{
j++;
}
keepRunning.store(true, std::memory_order_release); //ends the loop thread.
}
int main(){
std::thread first (loop); //start the loop thread
std::thread second (countSafe); //start the countSafe thread. Without this it doesn't work.
//Why does polling for std::cin.get() here not work?
//std::cin.get(); //wait for key press. puts in buffer..?
//keepRunning.store(true, std::memory_order_release); //Set stop to true.
second.join(); //pause to join.
first.join(); //pause to join
return 0;
}
I'm not quite sure what your problem is, but use of cin.get() might be part of it. Let's simplify with this code:
#include <iostream>
using namespace std;
int main(int, char **) {
cout << "Type something: ";
cin.get();
cout << "Done.\n";
}
Try that code and run it. Then type a single character. Chances are that the code won't recognize it. And you can type all you want until you hit return.
This is complicated, but your program doesn't actually receive the characters until you hit return unless you play other games. Like I said, it's complicated.
It's possible behavior is different on Windows, but this is the behavior on Mac and Linux.
So is it "not working" because you tried typing a space but you really need to use Return?
I'm trying to switch an application over from using boost::interprocess::named_mutex to boost::interprocess::file_lock for interprocess synchronization, but when I did so I noticed that my condition variables were never being woken up.
I've created two examples that demonstrate the types of changes I made and the issues I'm seeing. In both examples the same application should periodically send notifications if invoked with any arguments, or wait for notifications if invoked with no arguments
Originally my application used name_mutex and named_condition. The below example using name_mutex and named_condition works as expected: every time the "sender" application prints out "Notifying" the "receiver" application prints out "Notified!" (provided I manually clean out /dev/shm/ between runs).
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/thread.hpp>
int main(int argc, char** argv)
{
boost::interprocess::named_mutex mutex(boost::interprocess::open_or_create,
"mutex");
// Create condition variable
boost::interprocess::named_condition cond(boost::interprocess::open_or_create, "cond");
while(true)
{
if(argc > 1)
{// Sender
std::cout << "Notifying" << std::endl;
cond.notify_all();
boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
else
{// Receiver
std::cout << "Acquiring lock..." << std::endl;
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(mutex);
std::cout << "Locked. Waiting for notification..." << std::endl;
cond.wait(lock);
std::cout << "Notified!" << std::endl;
}
}
return 0;
}
The following code represents my attempt to change the working code above from using name_mutex and named_condition to using file_lock and named_condition_any
#include <iostream>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_condition_any.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/thread.hpp>
int main(int argc, char** argv)
{
// Second option for locking
boost::interprocess::file_lock flock("/tmp/flock");
// Create condition variable
boost::interprocess::named_condition_any cond(boost::interprocess::open_or_create,
"cond_any");
while(true)
{
if(argc > 1)
{// Sender
std::cout << "Notifying" << std::endl;
cond.notify_all();
boost::this_thread::sleep_for(boost::chrono::seconds(1));
}
else
{// Receiver
std::cout << "Acquiring lock..." << std::endl;
boost::interprocess::scoped_lock<boost::interprocess::file_lock> lock(flock);
std::cout << "Locked. Waiting for notification..." << std::endl;
cond.wait(lock);
std::cout << "Notified!" << std::endl;
}
}
return 0;
}
However I can't seem to get the "receiver" application to wake up when notified. The "sender" happily prints "Notifying" at ~1Hz, but the "receiver" hangs after printing "Locked. Waiting for notification..." once.
What am I doing wrong with my file_lock/named_condition_any implementation?
This appears to be caused by a bug in the implementation of boost::interprocess::named_condition_any.
boost::interprocess::named_condition_any is implemented using an instance of boost::interprocess::ipcdetail::shm_named_condition_any. boost::interprocess::ipcdetail::shm_named_condition_any has all of the member variables associated with its implementation aggregated into a class called internal_condition_members. When shm_named_condition_any is constructed it either creates or opens shared memory. If it creates the shared memory it also instantiates an internal_condition_members object in that shared memory.
The problem is that shm_named_condition_any also maintains a "local" (i.e. just on the stack, not in shared memory) member instance of an internal_condition_members object, and its wait, timed_wait, notify_one, and notify_all functions are all implemented using the local internal_condition_members member instead of the internal_condition_members from shared memory.
I was able to get the expected behavior from my example by editing boost/interprocess/sync/shm/named_condition_any.hpp and changing the implementation of the shm_named_condition_any class as follows:
typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
internal_condition m_cond;
to
typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition;
internal_condition &internal_cond()
{ return *static_cast<internal_condition*>(m_shmem.get_user_address()); }
and changing all usages of m_cond to this->internal_cond(). This is analogous to how the shm_named_condition class is implemented.
I have used mutex in inherited classes but seems it does not work as I expected with threads. Please have a look at below code:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
// mutex::lock/unlock
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::thread
#include <mutex> // std::mutex
typedef unsigned int UINT32t;
typedef int INT32t;
using namespace std;
class Abstract {
protected:
std::mutex mtx;
};
class Derived: public Abstract
{
public:
void* write( void* result)
{
UINT32t error[1];
UINT32t data = 34;
INT32t length = 0;
static INT32t counter = 0;
cout << "\t before Locking ..." << " in thread" << endl;
mtx.lock();
//critical section
cout << "\t After Create " << ++ counter << " device in thread" << endl;
std::this_thread::sleep_for(1s);
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
pthread_exit(result);
}
};
void* threadTest1( void* result)
{
Derived dev;
dev.write(nullptr);
}
int main()
{
unsigned char byData[1024] = {0};
ssize_t len;
void *status = 0, *status2 = 0;
int result = 0, result2 = 0;
pthread_t pth, pth2;
pthread_create(&pth, NULL, threadTest1, &result);
pthread_create(&pth2, NULL, threadTest1, &result2);
//wait for all kids to complete
pthread_join(pth, &status);
pthread_join(pth2, &status2);
if (status != 0) {
printf("result : %d\n",result);
} else {
printf("thread failed\n");
}
if (status2 != 0) {
printf("result2 : %d\n",result2);
} else {
printf("thread2 failed\n");
}
return -1;
}
so the result is:
*Four or five arguments expected.
before Locking ... in thread
After Create 1 device in thread
before Locking ... in thread
After Create 2 device in thread
deallocated 2 device in thread
deallocated 2 device in thread
thread failed
thread2 failed
*
So here we can see that second thread comes to critical section before mutex was deallocated.
The string "After Create 2 device in thread" says about that.
If it comes to critical section before mutex is deallocated it means mutex works wrong.
If you have any thoughts please share.
thanks
The mutex itself is (probably) working fine (I'd recommend you to use std::lock_guard though), but both threads create their own Derived object, hence, they don't use the same mutex.
Edit: tkausl's answer is correct -- however, even if you switch to using a global mutex, the output may not change because of the detail in my answer so I'm leaving it here. In other words, there are two reasons why the output may not be what you expect, and you need to fix both.
Note in particular these two lines:
mtx.unlock();
cout << "\t deallocated " << counter << " device in thread" << endl;
You seem to be under the impression that these two lines will be run one right after the other, but there is no guarantee that this will happen in a preemptive multithreading environment. What can happen instead is that right after mtx.unlock() there could be a context switch to the other thread.
In other words, the second thread is waiting for the mutex to unlock, but the first thread isn't printing the "deallocated" message before the second thread preempts it.
The simplest way to get the output you expect would be to swap the order of these two lines.
You shall declare your mutex as a global variable and initiate it before calling pthread_create. You created two threads using pthread_create and both of them create their own mutex so there is absolutely no synchronization between them.
I just get stuck in this code, I assumed that the code locks the global variable "a" for 30 seconds but the output doesn't satisfy this assumption. Could any one help me figure out why this happens and another question is that is there any function to lock required variable for a specific time, being specified by the programmer. Thank you in advanced for your consideration.
#include <iostream>
#include <ctime>
#include <pthread.h>
#include <time.h>
#include <chrono>
using namespace std;
// std::chrono::seconds interval(100);
timed_mutex test_mutex;
int a = 0;
void * write(void * args)
{
auto start=std::chrono::steady_clock::now();
test_mutex.try_lock_until(start+std::chrono::seconds(30));
a = 2;
cout << "Here is place #" << a << endl;
test_mutex.unlock();
pthread_exit(NULL);
}
int main()
{
auto start=std::chrono::steady_clock::now();
pthread_t check;
pthread_create(&check, NULL, &write, NULL);
test_mutex.try_lock_until(start+std::chrono::seconds(30));
a = 1;
cout << "Here is place #" << a << endl;
test_mutex.unlock();
pthread_join(check, NULL);
return 0;
}
std::timed_mutex::try_lock_until returns either:
true when the mutex is acquired, or
false if it timed out (waited as long as allowed) trying to lock the mutex
Note that this code is buggy anyway, because it doesn't check the return value. So, a can be written even if the mutex was not acquired.
I am trying to make use of boost::thread to perform "n" similar jobs. Of course, "n" in general could be exorbitantly high and so I want to restrict the number of simultaneously running threads to some small number m (say 8). I wrote something like the following, where I open 11 text files, four at a time using four threads.
I have a small class parallel (which upon invoking run() method would open an output file and write a line to it, taking in a int variable. The compilation goes smoothly and the program runs without any warning. The result however is not as expected. The files are created, but they are not always 11 in number. Does anyone know what's the mistake I am making?
Here's parallel.hpp:
#include <fstream>
#include <iostream>
#include <boost/thread.hpp>
class parallel{
public:
int m_start;
parallel()
{ }
// member function
void run(int start=2);
};
The parallel.cpp implementation file is
#include "parallel.hpp"
void parallel::run(int start){
m_start = start;
std::cout << "I am " << m_start << "! Thread # "
<< boost::this_thread::get_id()
<< " work started!" << std::endl;
std::string fname("test-");
std::ostringstream buffer;
buffer << m_start << ".txt";
fname.append(buffer.str());
std::fstream output;
output.open(fname.c_str(), std::ios::out);
output << "Hi, I am " << m_start << std::endl;
output.close();
std::cout << "Thread # "
<< boost::this_thread::get_id()
<< " work finished!" << std::endl;
}
And the main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "parallel.hpp"
int main(int argc, char* argv[]){
std::cout << "main: startup!" << std::endl;
std::cout << boost::thread::hardware_concurrency() << std::endl;
parallel p;
int populationSize(11), concurrency(3);
// define concurrent thread group
std::vector<boost::shared_ptr<boost::thread> > threads;
// population one-by-one
while(populationSize >= 0) {
// concurrent threads
for(int i = 0; i < concurrency; i++){
// create a thread
boost::shared_ptr<boost::thread>
thread(new boost::thread(¶llel::run, &p, populationSize--));
threads.push_back(thread);
}
// run the threads
for(int i =0; i < concurrency; i++)
threads[i]->join();
threads.clear();
}
return 0;
}
You have a single parallel object with a single m_start member variable, which all threads access without any synchronization.
Update
This race condition seems to be a consequence of a design problem. It is unclear what an object of type parallel is meant to represent.
If it is meant to represent a thread, then one object should be allocated for each thread created. The program as posted has a single object and many threads.
If it is meant to represent a group of threads, then it should not keep data that belongs to individual threads.