passing std::string to native thread - multithreading

I need to pass binary data to a native thread.
I am using std::string to keep the binary data, I came up with an idea how to pass std::string to a native string, and want to know if it is safe.
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
string binaryDataInThread = string(*(string*)lpParam); // copy data to current thread
while (true)
{// do some stuff with binaryDataInThread
cout << "thread binaryData size: " << binaryDataInThread.size() << endl;
Sleep(1000);
}
return 0;
}
int main(int argc, char *argv[])
{
{
string binaryDataInMain;
for (int i = 0; i < 500; i++)
binaryDataInMain += (char)i;
CloseHandle(CreateThread(NULL, NULL, MyThreadFunction, &binaryDataInMain, NULL, NULL));
Sleep(1000); // wait for thread to copy data
} // destroy binaryDataInMain
system("pause");
ExitProcess(0);
}
the size of binaryDataInThread is 500, so all binary data has passed successfully. but is it safe?

No your method is not save, although it is unlikely to fail. Under odd circumstances, even the second you wait for the thread to copy the data is not enough.
Suggestions:
Use C++ threads.
If for some odd reason you can't use C++ threads, fix those reasons!
If you pass data to a thread that you want to avoid sharing, allocate the data dynamically using new. Of course, the thread will then be responsible for releasing the data using delete!
If you want to share data with a thread, synchronize access to it using the various sychronization primitives available (mutex, events etc).
As alternative, use atomic operations on primitive types. However, lock-free programming is hard and correct lock-free programming is even harder. This is not for beginners!

Related

Does a condition variable really need another variable?

Note: I'll give examples in C++ but I believe my question is language-agnostic. Correct me if I'm wrong.
Just so you really understand me - what I'm trying to learn here is what the tool does and nothing else. Not what it's usually used for, not what the conventions says, just what the blunt tool does. In this case - what the condition variable does.
So far it seems to me like it's a simple mechanism that allows threads to wait (block) until some other thread signals them (unblocks them). Nothing more, no dealing with critical section access or data access (of course they can be used for that but it's only a matter of programmer's choice). Also the signaling is usually only done when something important happens (e.g. data was loaded) but theoretically it could be called at any time. Correct so far?
Now, every example that I have seen uses a condition variable object (e.g. std::condition_variable) but also some additional variable to mark if something happened (e.g. bool dataWasLoaded). Take a look at this example from https://thispointer.com//c11-multithreading-part-7-condition-variables-explained/:
#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
std::mutex m_mutex;
std::condition_variable m_condVar;
bool m_bDataLoaded;
public:
Application()
{
m_bDataLoaded = false;
}
void loadData()
{
// Make This Thread sleep for 1 Second
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "Loading Data from XML" << std::endl;
// Lock The Data structure
std::lock_guard<std::mutex> guard(m_mutex);
// Set the flag to true, means data is loaded
m_bDataLoaded = true;
// Notify the condition variable
m_condVar.notify_one();
}
bool isDataLoaded()
{
return m_bDataLoaded;
}
void mainTask()
{
std::cout << "Do Some Handshaking" << std::endl;
// Acquire the lock
std::unique_lock<std::mutex> mlock(m_mutex);
// Start waiting for the Condition Variable to get signaled
// Wait() will internally release the lock and make the thread to block
// As soon as condition variable get signaled, resume the thread and
// again acquire the lock. Then check if condition is met or not
// If condition is met then continue else again go in wait.
m_condVar.wait(mlock, std::bind(&Application::isDataLoaded, this));
std::cout << "Do Processing On loaded Data" << std::endl;
}
};
int main()
{
Application app;
std::thread thread_1(&Application::mainTask, &app);
std::thread thread_2(&Application::loadData, &app);
thread_2.join();
thread_1.join();
return 0;
}
Now, other than the std::condition_variable m_condVar it also uses an additional variable bool m_bDataLoaded. But it seems to me that the thread performing mainTask is already notified that the data was loaded by means of std::condition_variable m_condVar. Why also check bool m_bDataLoaded for the same information? Compare (the same code without bool m_bDataLoaded):
#include <iostream>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std::placeholders;
class Application
{
std::mutex m_mutex;
std::condition_variable m_condVar;
public:
Application()
{
}
void loadData()
{
// Make This Thread sleep for 1 Second
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "Loading Data from XML" << std::endl;
// Lock The Data structure
std::lock_guard<std::mutex> guard(m_mutex);
// Notify the condition variable
m_condVar.notify_one();
}
void mainTask()
{
std::cout << "Do Some Handshaking" << std::endl;
// Acquire the lock
std::unique_lock<std::mutex> mlock(m_mutex);
// Start waiting for the Condition Variable to get signaled
// Wait() will internally release the lock and make the thread to block
// As soon as condition variable get signaled, resume the thread and
// again acquire the lock. Then check if condition is met or not
// If condition is met then continue else again go in wait.
m_condVar.wait(mlock);
std::cout << "Do Processing On loaded Data" << std::endl;
}
};
int main()
{
Application app;
std::thread thread_1(&Application::mainTask, &app);
std::thread thread_2(&Application::loadData, &app);
thread_2.join();
thread_1.join();
return 0;
}
Now I know about spurious wakeups and they alone necessitate the usage of an additional variable. My question is - are they they only reason for it? If they didn't occur could one just use condition variables without any additional variables (and btw wouldn't that make the name "condition variable" a misnomer then)?
Another thing is - isn't the usage of additional variables the only reason why condition variables also require a mutex? If not, what are the other reasons?
If additional variables are necessary (for spurious wakeups or other reasons) why doesn't the API require them (in the 2nd code I didn't have to use them for the code to compile)? (I don't know if it's the same in other languages, so this question might be C++-specific.)
It's not all about spurious wakeups.
When you call m_condvar.wait, how do you know the condition you're waiting for has not already happened?
Maybe 'loadData' has already been called in another thread. When it called notify_one(), nothing happened because there were no threads waiting.
Now if you call condvar.wait, you will wait forever because nothing will signal you.
The original version does not have this problem, because:
If m_bDataLoaded is false, then it knows that the data is not loaded, and that after m_bDataLoaded is set true, the caller will signal the condition;
The lock is held, and we know that m_bDataLoaded cannot be modified in another thread until it's released;
condvar.wait will put the current thread in the waiting queue before releasing the lock, so we know that m_bDataLoaded will be set true after we start waiting, and so notify_one will also be called after we start waiting.
To answer your other questions:
Yes, coordination with additional variables is the reason why condition variables are tied to mutexes.
The API doesn't require, say, a boolean variable, because that's not always the kind of condition you're waiting for.
This kind of thing is common, for example:
Task *getTask() {
//anyone who uses m_taskQueue or m_shutDown must lock this mutex
unique_lock<mutex> lock(m_mutex);
while (m_taskQueue.isEmpty()) {
if (m_shutdown) {
return null;
}
// this is signalled after a task is enqueued
// or m_shutdown is asserted
m_condvar.wait(lock);
}
return taskQueue.pop_front();
}
Here we require the same critical guarantee that the thread starts waiting before the lock is released, but the condition we're waiting for is more complex, involving a variable and separate data structure, and there are multiple ways to exit the wait.
Yes, the condition variable is just useful to wait for an event. In my point of view you should not try to use it for controlling concurrent access of critical data structures.
I just can speak about C++. As you see in the example here https://en.cppreference.com/w/cpp/thread/condition_variable/wait, they used this expression cv.wait(lk, []{return i == 1;});. And []{...} is the expression of a nameless function. So you can also write your own function and give the name of the function:
bool condFn()
{
std::cout << "condFn" << std::endl; // debug output ;)
return i == 1;
}
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cerr << "Waiting... \n";
cv.wait(lk, condFn);
std::cerr << "...finished waiting. i == 1\n";
}
And inside this function you can evaluate, whatever you want. The thread is always sleeping until it gets notified, then it processes always the function that evaluates the condition for continue working. In case of true, the thread continues, in case of false the programm goes sleeping again.

How to move/swap a std::vector efficiently and thread safe?

Imagine a thread which continuously writes to a vector of strings which is being collected every now and then by another thread (see code).
#include <string>
#include <vector>
#include <chrono>
#include <thread>
#include <iostream>
#include <cassert>
// some public vector being filled by one and consumed by another
// thread
static std::vector<std::string> buffer;
// continuously writes data to buffer (has to be fast)
static const auto filler(std::thread([] {
for (size_t i = 0;; ++i) {
buffer.push_back(std::to_string(i));
}
}));
// returns collected data and clears the buffer being written to
std::vector<std::string> fetch() {
return std::move(buffer);
}
// continuously fetch buffered data and process it (can be slow)
int main() {
size_t expected{};
for(;;) {
std::this_thread::sleep_for(std::chrono::seconds(1));
const auto fetched(fetch());
for (auto && e : fetched) {
size_t read(std::stoi(e));
std::cout << read << " " << expected << std::endl;
assert(read == expected);
++expected;
}
}
}
The provided example generally does what I want it to do but it crashes because it's not thread safe. Obvious approaches would be
to secure the shared vector using a lock_guard
using two buffers and an atomic pointer
using a thread safe vector implementation.
The provided scenario seems very simple to me. I don't think I need a thread safe vector because that would cover a lot more scenarios at the cost of performance.
Using a mutex or swapping between two instances of the vector seem plausible to me but I wonder if there is some solution specially made to 'atomically grab all data and leave an empty container'.
Maybe there's an obvious solution and it's just time to go to bed for me?
Important note: this question is somewhat academical since performance is not (necessarily) a real issue here. The provided example gets throttled by about 15% but there is hardly any 'real' work being done. I think in a real world example the benefit would be about 2-5%
First of all I would not recommend to have a non-const static variable. So I propose to encapsulate vector with a class with the following interface
class ValuesHolder
{
public:
void push_back(std::string value);
std::vector<std::string> take();
};
The second note about 'atomically grab all data and leave an empty container' - you could make this trick with swapping pointers but the main issue is that push_back should be in a sync with it (during the push_back is executed vector shouldn't be moved). Otherwise there may be issues with the following workflow
Thead 1 Thread 2
auto values = holder.take(); // push_back starts before take
for (const auto& value : values) // but value is inserted during the iteration
{...}
So the first option is just to lock during both calls:
class ValuesHolder
{
public:
void push_back(std::string value)
{
std::lock_guard<std::mutex> lock(mut);
values.push_back(std::move(value));
}
std::vector<std::string> take()
{
std::lock_guard<std::mutex> lock(mut);
return std::move(values);
}
private:
std::mutex mut;
std::vector<std::string> values;
};
Otherwise you could switch from std::vector to lock-free stack container. However the performance should be accurately measured since the number of allocations can increase, so the performance can be worser.

C++11 thread detach not working

I understand that when a new thread is spawned it must be joined or detached else terminate shall be called, i have the below piece of code which work fine if i join them, but crashes if i call detach instead, I am not able to understand what's going on under the hood.
#include "iostream"
#include "thread"
#include "vector"
#include "algorithm"
#include "iterator"
#include "string"
#include "memory"
using namespace std;
void func() {
cout << " func ";
}
int main(int argc , char** argv)
{
std::vector< std::thread> m_vec;
for(int i = 0; i < 100 ; i++){
m_vec.push_back( std::thread(func));
m_vec[i].detach();
}
return 0;
}
Just detaching a thread doesn't give it permission to outlive the main thread. Once the main thread exits, that's the ballgame; the heap is destroyed, things like cout are cleaned up. Any remaining threads stand a distinct chance of crashing if they do anything before the process as a whole terminates.
If you detach a thread, be prepared to provide your own mechanism for ensuring it does not outlive the main thread.

How can man put a thread(in boost) which is created with packaged_task, into a shared_ptr vector

this is a example from boost library.
int calculate_the_answer_to_life_the_universe_and_everything()
{
return 42;
}
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost:: future<int> fi=pt.get_future();
instead of boost::thread task(boost::move(pt)); to launch a task on the thread,
now I want to put the thread into shared_ptr vector and launch a task on the thread.
First i creat a vector.
std::vector<std::shared_ptr<boost::thread>> vecThreads;
And is this the right way to put a thread into vector?
vecThreads.push_back(std::make_shared<boost::thread>(boost::packaged_task<int> &pt));
thank you all for the attention!
Packaged tasks are just that. They don't "have" threads.
They just run on a thread. Any thread.
In fact, it's an anti-pattern to start a thread for each task. But, of course, you can. I'd suggest using a
boost::thead_group tg;
tg.create_thread(std::move(pt));
So you can depend on
tg.join_all();
to await all pending threads completion.
UPDATE
With shared pointers, here's an example:
Live On Coliru
#include <boost/thread.hpp>
#include <boost/make_shared.hpp>
#include <boost/bind.hpp>
using namespace boost;
int ltuae(int factor) {
this_thread::sleep_for(chrono::milliseconds(rand()%1000));
return factor*42;
}
int main() {
std::vector<unique_future<int> > futures;
std::vector<shared_ptr<thread> > threads;
for (int i=0; i<10; ++i)
{
packaged_task<int> pt(bind(ltuae, i));
futures.emplace_back(pt.get_future());
threads.emplace_back(make_shared<thread>(std::move(pt)));
}
for (auto& f : futures)
std::cout << "Return: " << f.get() << "\n";
for (auto& t: threads)
if (t->joinable())
t->join();
}

How to join a thread in Linux kernel?

The main question is: How we can wait for a thread in Linux kernel to complete? I have seen a few post concerned about proper way of handling threads in Linux kernel but i'm not sure how we can wait for a single thread in the main thread to be completed (suppose we need the thread[3] be done then proceed):
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/slab.h>
void *func(void *arg) {
// doing something
return NULL;
}
int init_module(void) {
struct task_struct* thread[5];
int i;
for(i=0; i<5; i++) {
thread[i] = kthread_run(func, (void*) arg, "Creating thread");
}
return 0;
}
void cleanup_module(void) {
printk("cleaning up!\n");
}
AFAIK there is no equivalent of pthread_join() in kernel. Also, I feel like your pattern (of starting bunch of threads and waiting only for one of them) is not really common in kernel. That being said, there kernel does have few synchronization mechanism that may be used to accomplish your goal.
Note that those mechanisms will not guarantee that the thread finished, they will only let main thread know that they finished doing the work they were supposed to do. It may still take some time to really stop this tread and free all resources.
Semaphores
You can create a locked semaphore, then call down in your main thread. This will put it to sleep. Then you will up this semaphore inside of your thread just before exiting. Something like:
struct semaphore sem;
int func(void *arg) {
struct semaphore *sem = (struct semaphore*)arg; // you could use global instead
// do something
up(sem);
return 0;
}
int init_module(void) {
// some initialization
init_MUTEX_LOCKED(&sem);
kthread_run(&func, (void*) &sem, "Creating thread");
down(&sem); // this will block until thread runs up()
}
This should work but is not the most optimal solution. I mention this as it's a known pattern that is also used in userspace. Semaphores in kernel are designed for cases where it's mostly available and this case has high contention. So a similar mechanism optimized for this case was created.
Completions
You can declare completions using:
struct completion comp;
init_completion(&comp);
or:
DECLARE_COMPLETION(comp);
Then you can use wait_for_completion(&comp); instead of down() to wait in main thread and complete(&comp); instead of up() in your thread.
Here's the full example:
DECLARE_COMPLETION(comp);
struct my_data {
int id;
struct completion *comp;
};
int func(void *arg) {
struct my_data *data = (struct my_data*)arg;
// doing something
if (data->id == 3)
complete(data->comp);
return 0;
}
int init_module(void) {
struct my_data *data[] = kmalloc(sizeof(struct my_data)*N, GFP_KERNEL);
// some initialization
for (int i=0; i<N; i++) {
data[i]->comp = &comp;
data[i]->id = i;
kthread_run(func, (void*) data[i], "my_thread%d", i);
}
wait_for_completion(&comp); // this will block until some thread runs complete()
}
Multiple threads
I don't really see why you would start 5 identical threads and only want to wait for 3rd one but of course you could send different data to each thread, with a field describing it's id, and then call up or complete only if this id equals 3. That's shown in the completion example. There are other ways to do this, this is just one of them.
Word of caution
Go read some more about those mechanisms before using any of them. There are some important details I did not write about here. Also those examples are simplified and not tested, they are here just to show the overall idea.
kthread_stop() is a kernel's way for wait thread to end.
Aside from waiting, kthread_stop() also sets should_stop flag for waited thread and wake up it, if needed. It is usefull for threads which repeat some actions infinitely.
As for single-shot tasks, it is usually simpler to use works for them, instead of kthreads.
EDIT:
Note: kthread_stop() can be called only when kthread(task_struct) structure is not freed.
Either thread function should return only after it found kthread_should_stop() return true, or get_task_struct() should be called before start thread (and put_task_struct() should be called after kthread_stop()).

Resources