Threading in c++ - c++

Lets say I want to take an input from user and perform a search in a text file for that input. The search will be performed for every character user inputs. There will be a loop performing search and there will be another loop to check if new character is input by the user. Second loop will restart the first loop if new char is given by the user.
Please just explain how to perform above with c++. I think threads need to be created.
Below variables will be used to maintain common values:
static var`
bool change;
while(!change)
{
change=false
<<do something, like search in file>>
}
Other loop will be like below:
while(1)
{
if(user enters another char)
{
var=new value input by the user;
change=true;
}
else change=false;
}
Thanks!

Something like this? Now I wrote this on ideone and their threads didn't work for me so I wasn't able to test it but yeah.. Something close to this should work. Probably a bad example. A thread pool would be best.
#include <iostream>
#include <thread>
#include <atomic>
#include <queue>
#include <mutex>
#include <chrono>
std::mutex lock;
std::atomic<bool> stop(false);
std::queue<std::function<void()>> jobs;
void One()
{
while(!stop)
{
if (!jobs.empty())
{
if (lock.try_lock())
{
std::function<void()> job = jobs.front();
jobs.pop();
lock.unlock();
job();
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void Two()
{
std::string var;
while(true)
{
if (std::cin>> var)
{
std::lock_guard<std::mutex> glock(lock);
jobs.push([] {std::cout<<"Task added to the queue..\n";});
}
else
break;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
std::thread T(One);
Two();
stop = true;
T.join();
return 0;
}

Create two threads: one for reading user-input, and another for performing the search.
Use a binary-semaphore in order to synchronize between the two threads in a Consumer-Producer manner, i.e., one thread acquires the semaphore and the other thread releases it:
static BinarySemaphore binSem;
static int inputCharacter = 0;
static void ReadUserInput();
static void PerformSearch();
void Run()
{
BinarySemaphore_Init(&binSem,0);
CreateThread(ReadUserInput,LOWER_PRIORITY);
CreateThread(PerformSearch,HIGHER_PRIORITY);
}
static void ReadUserInput()
{
while (inputCharacter != '\n')
{
inputCharacter = getc(stdin);
BinarySemaphore_Set(&binSem);
}
}
static void PerformSearch()
{
while (inputCharacter != '\n')
{
BinarySemaphore_Get(&binSem,WAIT_FOREVER);
// <<do something, like search in file>>
}
}
Please note that you need to create the thread which performs the search, with priority higher than that of the thread which reads user-input (as in the code above).

Related

Are I/O streams really thread-safe?

I wrote a program that writes random numbers to one file in the first thread, and another thread reads them from there and writes to another file those that are prime numbers. The third thread is needed to stop/start the work. I read that I/O threads are thread-safe. Since writing to a single shared resource is thread-safe, what could be the problem?
Output: always correct record in numbers.log, sometimes no record in numbers_prime.log when there are prime numbers, sometimes they are all written.
#include <iostream>
#include <fstream>
#include <thread>
#include <mutex>
#include <vector>
#include <condition_variable>
#include <future>
#include <random>
#include <chrono>
#include <string>
using namespace std::chrono_literals;
std::atomic_int ITER_NUMBERS = 30;
std::atomic_bool _var = false;
bool ret() { return _var; }
std::atomic_bool _var_log = false;
bool ret_log() { return _var_log; }
std::condition_variable cv;
std::condition_variable cv_log;
std::mutex mtx;
std::mutex mt;
std::atomic<int> count{0};
std::atomic<bool> _FL = 1;
int MIN = 100;
int MAX = 200;
bool is_empty(std::ifstream& pFile) // function that checks if the file is empty
{
return pFile.peek() == std::ifstream::traits_type::eof();
}
bool isPrime(int n) // function that checks if the number is prime
{
if (n <= 1)
return false;
for (int i = 2; i <= sqrt(n); i++)
if (n % i == 0)
return false;
return true;
}
void Log(int min, int max) { // function that generates random numbers and writes them to a file numbers.log
std::string str;
std::ofstream log;
std::random_device seed;
std::mt19937 gen{seed()};
std::uniform_int_distribution dist{min, max};
log.open("numbers.log", std::ios_base::trunc);
for (int i = 0; i < ITER_NUMBERS; ++i, ++count) {
std::unique_lock<std::mutex> ulm(mtx);
cv.wait(ulm,ret);
str = std::to_string(dist(gen)) + '\n';
log.write(str.c_str(), str.length());
log.flush();
_var_log = true;
cv_log.notify_one();
//_var_log = false;
//std::this_thread::sleep_for(std::chrono::microseconds(500000));
}
log.close();
_var_log = true;
cv_log.notify_one();
_FL = 0;
}
void printCheck() { // Checking function to start/stop printing
std::cout << "Log to file? [y/n]\n";
while (_FL) {
char input;
std::cin >> input;
std::cin.clear();
if (input == 'y') {
_var = true;
cv.notify_one();
}
if (input == 'n') {
_var = false;
}
}
}
void primeLog() { // a function that reads files from numbers.log and writes prime numbers to numbers_prime.log
std::unique_lock ul(mt);
int number = 0;
std::ifstream in("numbers.log");
std::ofstream out("numbers_prime.log", std::ios_base::trunc);
if (is_empty(in)) {
cv_log.wait(ul, ret_log);
}
int oldCount{};
for (int i = 0; i < ITER_NUMBERS; ++i) {
if (oldCount == count && count != ITER_NUMBERS) { // check if primeLog is faster than Log. If it is faster, then we wait to continue
cv_log.wait(ul, ret_log);
_var_log = false;
}
if (!in.eof()) {
in >> number;
if (isPrime(number)) {
out << number;
out << "\n";
}
oldCount = count;
}
}
}
int main() {
std::thread t1(printCheck);
std::thread t2(Log, MIN, MAX);
std::thread t3(primeLog);
t1.join();
t2.join();
t3.join();
return 0;
}
This has nothing to do with the I/O stream thread safety. The shown code's logic is broken.
The shown code seems to follow a design pattern of breaking up a single logical algorithm into multiple pieces, and scattering them far and wide. This makes it more difficult to understand what it's doing. So let's rewrite a little bit of it, to make the logic more clear. In primeLog let's do this instead:
cv_log.wait(ul, []{ return _var_log; });
_var_log = false;
It's now more clear that this waits for _var_log to be set, before proceeding on its merry way. Once it is it gets immediately reset.
The code that follows reads exactly one number from the file, before looping back here. So, primeLog's main loop will always handle exactly one number, on each iteration of the loop.
The problem now is very easy to see, once we head over to the other side, and do the same clarification:
std::unique_lock<std::mutex> ulm(mtx);
cv.wait(ulm,[]){ return _var; });
// Code that generates one number and writes it to the file
_var_log = true;
cv_log.notify_one();
Once _var is set to true, it remains true. This loops starts running full blast, iterating continuously. On each iteration of the loop it blindly sets _var_log to true and signals the other thread's condition variable.
C++ execution threads are completely independent of each other unless they are explicitly synchronize in some way.
Nothing is preventing this loop from running full blast, getting through its entire number range, before the other execution thread wakes up and decides to read the first number from the file. It'll do that, then go back and wait for its condition variable to be signaled again, for the next number. Its hopes and dreams of the 2nd number will be left unsatisfied.
On each iteration of the generating thread's loop the condition variable, for the other execution thread, gets signaled.
Condition variables are not semaphores. If nothing is waiting on a condition variable when it's signaled -- too bad. When some execution thread decides to wait on a condition variable, it may or may not be immediately woken up.
One of these two execution thread relies on it receiving a condition variable notification for every iteration of its loop.
The logic in the other execution thread fails to implement this guarantee. This may not be the only flaw, there might be others, subject to further analysis, this was just the most apparent logical flaw.
Thanks to those who wrote about read-behind-write, now I know more. But that was not the problem. The main problem was that if it was a new file, when calling pFile.peek() in the is_empty function, we permanently set the file flag to eofbit. Thus, until the end of the program in.rdstate() == std::ios_base::eofbit.
Fix: reset the flag state.
if (is_empty(in)) {
cv_log.wait(ul, ret_log);
}
in.clear(); // reset state
There was also a problem with the peculiarity of reading/writing one file from different threads, though it was not the cause of my program error, but it led to another one.
Because if when I run the program again primeLog() opens std::ifstream in("numbers.log") for reading faster than log.open("numbers.log", std::ios_base::trunc), then in will save old data into its buffer faster than log.open will erase them with the std::ios_base::trunc flag. Hence we will read and write to numbers_prime.log the old data.

Function Objects & multithreading Pool giving same thread ID

For below program, thread Pool always picks the same thread ID 0x7000095f9000! Why so?
Should every push condi.notify_one() wake up all threads same time? What could be the reason same thread ID get picked?
Computer supports 3 threads.
Any other info on using function objects would be helpful!!
O/P
Checking if not empty
Not Empty
0x700009576000 0
Checking if not empty
Checking if not empty
Checking if not empty
Not Empty
0x7000095f9000 1
Checking if not empty
Not Empty
0x7000095f9000 2
Checking if not empty
Not Empty
0x7000095f9000 3
Checking if not empty
Not Empty
0x7000095f9000 4
Checking if not empty
Not Empty
0x7000095f9000 5
Checking if not empty
Code
#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <condition_variable>
#include <chrono>
using namespace std;
class TestClass{
public:
void producer(int i) {
unique_lock<mutex> lockGuard(mtx);
Q.push(i);
cond.notify_all();
}
void consumer() {
{
unique_lock<mutex> lockGuard(mtx);
cout << "Checking if not empty" << endl;
cond.wait(lockGuard, [this]() {
return !Q.empty();
});
cout << "Not Empty" << endl;
cout << this_thread::get_id()<<" "<<Q.front()<<endl;
Q.pop();
}
};
void consumerMain() {
while(1) {
consumer();
std::this_thread::sleep_for(chrono::seconds(1));
}
}
private:
mutex mtx;
condition_variable cond;
queue<int> Q;
};
int main()
{
std::vector<std::thread> vecOfThreads;
std::function<void(TestClass&)> func = [&](TestClass &obj) {
while(1) {
obj.consumer();
}
};
unsigned MAX_THREADS = std::thread::hardware_concurrency()-1;
TestClass obj;
for(int i=0; i<MAX_THREADS; i++) {
std::thread th1(func, std::ref(obj));
vecOfThreads.emplace_back(std::move(th1));
}
for(int i=0; i<4*MAX_THREADS/2; i++) {
obj.producer(i);
}
for (std::thread & th : vecOfThreads)
{
if (th.joinable())
th.join();
}
return 0;
}
Any other info on using function objects would be helpful!! Thanks in advance!!
Any other pointers?
The very short unlocking of the mutex that happens in the consumer threads will in your case most probably let the running thread acquire the lock again, and again and again.
If you instead simulate some work being done after the workload has been picked from the queue by calling consumerMain (which sleeps a little) instead of consumer, you would likely see different threads picking up the workload.
while(1) {
obj.consumerMain();
}

stopping a while / for loop when an user says so

i'm new to c++ so I only kind of know iostream and the syntax of the language.
I am writing a program that creates an infinite amount of .txt files using fstream but i'm kind of stuck, I want it to have a menu in the program so the user could interfere with the process with the help of commands I will code in void functions("pause", "stop", etc...)
It means that the process of creating .txt files should run constantly but that the user could also write in a cin>> the keywords shown above to interfere with the process
I plan to write multiple commands so I'll surely use switch statement in the future but to show you my problem I'll only use a while loop with one command
So I've tried things like that:
void stop()
{
return 0;
}
int main()
{
string command= "";
int i=1;
if (command!="stop")
{
while (i<=2)
{
CreateNewFile();
cin >> command;
}
} else
{
stop();
}
}
But the problem with this kind of loop is that it asks the user to write something everytime in order to reset the loop and it is this thing in particular that I want to avoid...
I want to keep the loop running as long as my user wants it to
I'm sure that the answer is really simple but i've not found any help by asking google so i'll tr to ask you guys.
Thank you in advance to those who will take the time to asnwer me
My advise, Adam, is to change your problem description so you ask user how many files they want to create, and then run the loop that many times:
for(;;) {
unsigned n;
cout << "How many files do you want to create (0 to stop)? ";
cin >> n;
if(!n) break;
for(unsigned i = 0; i < n; i++) {
CreateNewFile();
}
}
I had something on this line wherein the thread that's doing the actual work continues and only processes commands if the user wants to.
#include <iostream>
#include <string>
#include <thread>
#include <stack>
#include <chrono>
#include <mutex>
int main() {
std::stack<std::string> commandQueue;
std::mutex m;
int i = 0;
std::thread worker([&]() {
bool suspend = false;
while(true) {
{
const std::lock_guard<std::mutex> lock(m);
if(!commandQueue.empty()){
std::string command = commandQueue.top();
commandQueue.pop();
if(command == "continue"){
suspend = false;
//process continue
} else if (command == "pause"){
suspend = true;
//process other commands....
} else if(command == "stop") {
//process stop
return; //exit thread
}
}
}
//Commands processed, continue as usual
if(!suspend) {//Process only if not paused
using namespace std::chrono_literals;
//Continue creating files or whatever it is that needs to be done continuously
std::this_thread::sleep_for(500ms);
i++;
//std::cout<<"Value of i is "<<i<<'\n';
//CreatFileName();
}
}
});
std::string command;
do {
std::cout<<"Enter commands to interact\n";
std::cin>>command;
{
const std::lock_guard<std::mutex> lock(m);
commandQueue.push(command);
}
}while(command != "stop");
worker.join();
std::cout<<"After execution, value of i is "<<i<<'\n';
}
Of course, the output of this specific example is a bit ugly because it is printing to the console from 2 different threads but the commands like stop, pause, continue are processed fine since there's only one thread (the main thread) that reads in the commands but since this is just to demonstrate how one can possibly achieve what you intend to, I didn't spend up too much time on the output aesthetics.
So after a while this is basically the simplest solution:
#include <iostream>
#include <thread>
#include <string>
static bool finished = false;
void createFile() {
while (!finished) {
//Your code
}
}
int main() {
std::string answer;
std::thread question(createFile);
std::cin >> answer;
if (answer == "stop") {
finished = true;
}
question.join();
return 0;
}
Here we create a thread which will keep running until they type stop. I ran the code and it was working I made it print out 1 until I wrote stop.

Pause threads from a different thread, and then wait until all are paused

I want to pause a number of worker thread from a creator thread. This can be done with a conditional variable, as seen in this code.
#include <iostream>
#include <vector>
#include <thread>
#include <condition_variable>
#include <atomic>
#define NR_ITERATIONS 3
#define NR_THREADS 5
class c_threads {
private:
bool m_worker_threads_pause;
//std::atomic<int> m_worker_threads_paused;
std::mutex m_worker_thread_mutex;
std::condition_variable m_worker_thread_conditional_variable;
void worker_thread() {
std::unique_lock<std::mutex> worker_thread_lock(m_worker_thread_mutex);
m_worker_thread_conditional_variable.wait(worker_thread_lock,
[this]{return !this->m_worker_threads_pause;}
);
std::cout << "worker thread function" << std::endl;
//...
}
void creator_thread() {
std::cout << "creator thread function" << std::endl;
{
std::lock_guard<std::mutex> lock_guard(m_worker_thread_mutex);
m_worker_threads_pause = true;
}
// wait_until( worker_threads_waiting == NR_THREADS);
//...
{
std::lock_guard<std::mutex> lock_guard(m_worker_thread_mutex);
m_worker_threads_pause = false;
}
m_worker_thread_conditional_variable.notify_all();
}
public:
c_threads() : m_worker_threads_pause(true)
/*m_worker_threads_paused(0)*/ {}
void start_job() {
std::vector<std::thread> worker_threads;
worker_threads.reserve(NR_THREADS);
for (int i=0;i<NR_THREADS;i++) {
worker_threads.emplace_back(&c_threads::worker_thread,this);
}
std::thread o_creator_thread(&c_threads::creator_thread,this);
o_creator_thread.join();
for (auto& thread : worker_threads) {
thread.join();
}
}
};
int main(int argc, char** argv) {
c_threads o_threads;
o_threads.start_job();
}
The problem is that the creator_thread function should wait until all worker_functions are waiting at the conditional variable before it proceeds.
Every time that the creator_thread function is called it should
Pause the worker threads
Wait until they are all paused at the condition variable
Proceed
How to achieve this?
There might be a better way, but I think you're going to have to do something a little more complicated, like create a gatekeeper object. Worker threads generally work like this:
while(iShouldKeepRunning()) {
... lock the mutex
... look for something to do
... if nothing to do, then wait on the condition
}
I think instead you would want some sort of "give me more work" object, or maybe a "is it safe to keep working" object that your creater thread can block.
while(iShouldKeepRunning()) {
... no mutex at all
... ask the gatekeeper for something to do / if it's safe to do something
... and the gatekeeper blocks as necessary
... do the work
}
The gatekeeper locks the mutex, checks if it's safe to give out work, and if it isn't, increments a "I'm making this guy wait" counter before blocking on the condvar.
Something like that.
The blocker might look something like:
class BlockMyThreads {
public:
int runningCount = 0;
int blockedCount = 0;
bool mayWork = true;
std::mutex myMutex;
std::condition_variable condVar;
void iAmWorking() {
std::unique_lock<std::mutex> lock(myMutex);
++runningCount;
}
void letMeWork() {
std::unique_lock<std::mutex> lock(myMutex);
while (!mayWork) {
++blockedCount;
condVar.wait(lock);
--blockedCount;
}
}
void block() {
std::unique_lock<std::mutex> lock(myMutex);
mayWork = false;
}
void release() {
std::unique_lock<std::mutex> lock(myMutex);
mayWork = true;
condVar.notifyAll(lock);
}
};
I haven't tested this, so there might be errors. Your worker threads would need to call iAmWorking() at the start (to give you a thread count) and you'd want to increment a decrement they call when they're done, I suppose.
The main thread can call block() and release() as you desire.

Message passing between threads using a command file

This project asked for 4 threads that has a command file with
instructions such as SEND, Receive and quit. When the file says "2
send" the thread that in the second place in the array should wake
up and receive its message. I need to know how to make a thread read
it's message if the command file has a message for it?
The biggest issue I see for your design is the fact that each thread reads its line randomly independent from any other thread. After this it would have to check wether the current line is actually meant for it i.e. starting with the appropriate number. What happens if not ? Too complicated.
I would split this issue up into one reader thread and a set of worker threads. The first reads lines from a file and dispatches it to the workers by pushing it into the current workers queue. All synchronized with a per worker mutex and conditional variable The following is implemented in C++11 but should as well be doable in pthread_* style.
#include <thread>
#include <iostream>
#include <queue>
#include <mutex>
#include <fstream>
#include <list>
#include <sstream>
#include <condition_variable>
class worker {
public:
void operator()(int n) {
while(true) {
std::unique_lock<std::mutex> l(_m);
_c.wait(l);
if(!_q.empty()) {
{
std::unique_lock<std::mutex> l(_mm);
std::cerr << "#" << n << " " << _q.back() <<std::endl;
}
_q.pop();
}
}
}
private:
std::mutex _m;
std::condition_variable _c;
std::queue<std::string> _q;
// Only needed to synchronize I/O
static std::mutex _mm;
// Reader may write into our queue
friend class reader;
};
std::mutex worker::_mm;
class reader {
public:
reader(worker & w0,worker & w1,worker & w2,worker & w3) {
_v.push_back(&w0);
_v.push_back(&w1);
_v.push_back(&w2);
_v.push_back(&w3);
}
void operator()() {
std::ifstream fi("commands.txt");
std::string s;
while(std::getline(fi,s)) {
std::stringstream ss(s);
int n;
if((ss >> n >> std::ws) && n>=0 && n<_v.size()) {
std::string s0;
if(std::getline(ss,s0)) {
std::unique_lock<std::mutex> l(_v[n]->_m);
_v[n]->_q.push(s0);
_v[n]->_c.notify_one();
}
}
}
std::cerr << "done" << std::endl;
}
private:
std::vector<worker *> _v;
};
int main(int c,char **argv) {
worker w0;
worker w1;
worker w2;
worker w3;
std::thread tw0([&w0]() { w0(0); });
std::thread tw1([&w1]() { w1(1); });
std::thread tw2([&w2]() { w2(2); });
std::thread tw3([&w3]() { w3(3); });
reader r(w0,w1,w2,w3);
std::thread tr([&r]() { r(); });
tr.join();
tw0.join();
tw1.join();
tw2.join();
tw3.join();
}
The example code only reads from "commands.txt" until EOF. I assume you'd like to read continuously like the "tail -f" command. That's however not doable with std::istream.
The code of course is clumsy but I guess it gives you an idea. One should for example add a blocking mechanism if the workers are way too slow processing their stuff and the queues may eat up all the precious RAM.