I want to create a vector of threads which will doing same job, in my case I just want to take information from a vector of integers.
For example;
I will have got 4 threads and 10 integers.
My threads will get the integers' values. That's all. So I've coded this part but I couldn't solve how can I manage thread vector. How can I read values from this vector by waiting for each thread for the other thread? I would appreciate it if you explain with a sample code snippet.
std::condition_variable cond;
std::mutex m_mutex;
std::atomic<int> position_holder {0};
void access_fonksiyon(std::vector<int> myvec){
std::unique_lock<std::mutex> locked {m_mutex};
position_holder++;
std::cout << "Locked." << std::endl;
std::cout << "Position holder value : "
<< position_holder
<< "thread ID: "
<< std::this_thread::get_id()
<< std::endl;
}
int main(){
std::vector<int> myvec = {1,2,3,4,5,6,7,8,9};
std::vector<std::thread> thread_vec;
for(int i = 0; i < 2; i++){
thread_vec.push_back(std::thread(access_fonksiyon, std::ref(myvec)));
}
for (std::thread &reader : thread_vec){
reader.join();
}
return 0;
}
Related
I'm messing around with multithreading in c++ and here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <thread>
void read(int i);
bool isThreadEnabled;
std::thread threads[100];
int main()
{
isThreadEnabled = true; // I change this to compare the threaded vs non threaded method
if (isThreadEnabled)
{
for (int i = 0;i < 100;i++) //this for loop is what I'm confused about
{
threads[i] = std::thread(read,i);
}
for (int i = 0; i < 100; i++)
{
threads[i].join();
}
}
else
{
for (int i = 0; i < 100; i++)
{
read(i);
}
}
}
void read(int i)
{
int w = 0;
while (true) // wasting cpu cycles to actually see the difference between the threaded and non threaded
{
++w;
if (w == 100000000) break;
}
std::cout << i << std::endl;
}
in the for loop that uses threads the console prints values in a random order ex(5,40,26...) which is expected and totally fine since threads don't run in the same order as they were initiated...
but what confuses me is that the values printed are sometimes more than the maximum value that int i can reach (which is 100), values like 8000,2032,274... are also printed to the console even though i will never reach that number, I don't understand why ?
This line:
std::cout << i << std::endl;
is actually equivalent to
std::cout << i;
std::cout << std::endl;
And thus while thread safe (meaning there's no undefined behaviour), the order of execution is undefined. Given two threads the following execution is possible:
T20: std::cout << 20
T32: std::cout << 32
T20: std::cout << std::endl
T32: std::cout << std::endl
which results in 2032 in console (glued numbers) and an empty line.
The simplest (not necessarily the best) fix for that is to wrap this line with a shared mutex:
{
std::lock_guard lg { mutex };
std::cout << i << std::endl;
}
(the brackets for a separate scope are not needed if the std::cout << i << std::endl; is the last line in the function)
I am trying to understand thread-safe well, so, I have a simple code (code isn't real) that I have applied thread-safe as follow:
vector<int> myList;
const unsigned short ListSize = 5;
mutex mut;
condition_variable cond;
void AddItem() {
for (int i = 0; i < ListSize + 2; i++) {
mut.lock();
myList.push_back(i);
mut.unlock();
cond.notify_one();
cout << "An item added." << "\n";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
void RemoveItem() {
for (int i = 0; i < ListSize; i++) {
unique_lock<mutex> locker(mut);
cond.wait(locker, []() { return !myList.empty(); });
myList.erase(myList.begin());
cout << "An item removed." << "\n";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
int main() {
thread th_task1(&AddItem);
thread th_task2(&RemoveItem);
th_task1.join();
th_task2.join();
if (!myList.empty()) {
cout << "There are " << myList.size() << " items." << "\n";
} else {
cout << "The list is empty." << "\n";
}
return 0;
}
Also, you can test the code from here.
Is that code considered thread-safe? if not how to make it thread-safe?
It's thread-safe (as in, you lock when you should, and do wait properly), but it's not a very good use of threads, because you only notify the remove thread when the add thread has completely finished.
So you may as well just call AddItem() and then RemoveItem() directly from main.
Also, though I recognise the sleeps are just for experimenting, you probably want to consider bringing those sleeps out of the locks because otherwise, again, you're just creating lots of contention that stops the multi-threading from being in any way useful.
As we all known, we can generate one thread by std::thread t1(func); link
But how can we create 20 threads by vector?
An example solution would be:
std::vector<std::thread> my_threads{};
my_threads.reserve(20);
for(int i = 0; i < 20; i++)
my_threads.emplace_back([i]{
std::cout << "[" << i << "] Going to sleep\n";
this_thread::sleep_for(std::chrono::seconds{1});
std::cout << "[" << i << "] Hey I'm back :)\n";
});
for(auto& thread : my_threads)
if(thread.joinable())
thread.join();
Pay attention to the last tree lines.
If you don't join or detach your threads you'll get an abort.
This prevents your application from leaking unmanaged threads.
I have a program that pushes 10 threads into a vector, each of which is supposed to print out a character 5 times before finishing ('A' for the first thread, 'B' for the second, etc). I'm able to get them to either run all at once (using detach()) or have them run one at a time (using join()). Now I want to use a Mutex to limit the number of threads allowed to print at a time to 2. I've been able to declare the mutex and put the lock in place but I'm unsure of how to apply a limit like this. Anyone have any ideas on how to proceed?
deque<int> q ;
mutex print_mutex ;
mutex queue_mutex ;
condition_variable queue_cond ;
void begin(int num) {
unique_lock<mutex> ul {queue_mutex};
q.emplace_back(num);
queue_cond.wait(ul,[num]{
return q.front() == num; });
q.pop_front();
cout << num << " leaves begin " << endl ;
}
void end ( int num ) {
lock_guard<mutex>lg{queue_mutex};
queue_cond.notify_all();
cout << num << " has ended " << endl ;
}
void run(int num, char ch) {
begin(num);
for (int i = 0; i < 5; ++i) {
{
lock_guard<mutex> lg { print_mutex };
cout << ch << endl << flush ;
}
sleep_for(milliseconds(250));
}
end(num);
}
int main() {
vector<thread>threads {};
for (int i = 0; i < 10; ++i) {
threads.push_back(thread{run,i,static_cast<char>(65+i)});
threads.at(i).join();
}
}
You have already set up a FIFO for your threads with the global deque<int> q. So let's use that.
Currently, you're trying to restrict execution until the current thread is at the front. Although there's a bug, because begin will immediately pop that thread from the deque. Better to remove the value when you call end. Here's that change, first:
void end(int num)
{
{
lock_guard<mutex>lg{queue_mutex};
cout << num << " has ended " << endl ;
q.erase(find(q.begin(), q.end(), num));
}
queue_cond.notify_all();
}
This uses std::find from <algorithm> to remove the specific value. You could use pop_front, but we're about to change that logic so this is more generic. Also notice you don't need to lock the condition variable when you notify.
So, it's not much of a stretch to extend the logic in begin to be in the first two places. Here:
void begin(int num)
{
unique_lock<mutex> ul {queue_mutex};
q.emplace_back(num);
queue_cond.wait(ul,[num]{
auto end = q.begin() + std::min(2, static_cast<int>(q.size()));
return find(q.begin(), end, num) != end;
});
cout << num << " leaves begin " << endl ;
}
You can change that 2 to anything you want, allowing up to that many threads to pass. At some point, you would probably abandon this approach and use something simpler like a single counter variable, then rely on the thread scheduler to manage which thread is woken, rather than force them into your FIFO. That way you can switch to using notify_one to wake a single thread and reduce switching overhead.
Anyway, the last thing to do is remove the join from your thread generation loop. The concurrency is now managed by begin and end. So you would do this:
for (int i = 0; i < 10; ++i) {
threads.push_back( thread{run, i, 'A'+i} );
}
for (auto & t : threads) t.join();
My code:
#include <iostream>
#include <thread>
void function_1()
{
std::cout << "Thread t1 started!\n";
for (int j=0; j>-100; j--) {
std::cout << "t1 says: " << j << "\n";
}
}
int main()
{
std::thread t1(function_1); // t1 starts running
for (int i=0; i<100; i++) {
std::cout << "from main: " << i << "\n";
}
t1.join(); // main thread waits for t1 to finish
return 0;
}
I create a thread that prints numbers in decreasing order while main prints in increasing order.
Sample output here. Why is my code printing garbage ?
Both threads are outputting at the same time, thereby scrambling your output.
You need some kind of thread synchronization mechanism on the printing part.
See this answer for an example using a std::mutex combined with std::lock_guard for cout.
It's not "garbage" — it's the output you asked for! It's just jumbled up, because you have used a grand total of zero synchronisation mechanisms to prevent individual std::cout << ... << std::endl lines (which are not atomic) from being interrupted by similar lines (which are still not atomic) in the other thread.
Traditionally we'd lock a mutex around each of those lines.