I am new to threading, and i am trying to write a function that keep outputing an variable while i should be able to change that variable at runtime, and the output should change to my input once I input a new value in. By the following program is not running as i expected, whats wrong here? is there anything i can reference to so i can build this funciton out?
int a;
void* ptr;
void* Input(void* arg){
while(true){
std::cin >> a;
std::cout << std::endl;
}
return ptr;
}
void* Output(void *arg){
while(true){
std::cout << a << std::endl;
}
return ptr;
}
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
}
Your main thread is not waiting for your child thread and exited when main() returned. To make your main thread to wait for children finish their jobs, you should call pthread_join() for them.
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
pthread_join(GetInput, NULL);
pthread_join(GetOutput, NULL);
return 0;
}
Here's another alternative using std::async() for your code.
#include <chrono>
#include <future>
#include <iostream>
#include <mutex>
int a;
std::mutex mtx_;
void Input(void* arg) {
while (true) {
int tmp_a;
std::cin >> tmp_a;
{
std::lock_guard<std::mutex> lock(mtx_);
a = tmp_a;
}
std::cout << std::endl;
}
}
void Output(void* arg) {
while (true) {
{
std::lock_guard<std::mutex> lock(mtx_);
std::cout << a << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
auto ft_in = std::async(std::launch::async, Input, &a);
auto ft_out = std::async(std::launch::async, Output, &a);
ft_in.wait();
ft_out.wait();
return 0;
}
Well,I don't know how to use pthread.
And it seems Mr.john-park or Ms.john-park already gave a answer.
But I think use thread is a better choice.
To use it,we should:
#include<thread>
After that,if u want to start a new thread,and "connect" it with a function(In fact,we usually do)
There is a class named thread.
First,we should
thread *thread name*(*function name*);
WARNING:function nameshould be without "(" and ")"
May because here should be a pointer.
Then,to the question.
Suppose we wrote:
thread GetInput(Input);
thread GetOutput(Output);
When u want to stop GetOutput some time and run GetInput,
just
GetInput.join()
Here's a not so good example:
#include <iostream>
#include <thread>
using namespace std;
void f1()
{
while (true)
{
cout << "THREAD 1!" << endl;
}
}
void f2()
{
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
thread t1(f1);
t1.join();
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
}
int main()
{
thread t2(f2);
return 0;
}
First,we started t2.
Then t2 started t1.
Now we can know why we use join().
If we don't join(),
It'll be hard for us to read the output because it'll close the cmd window quickly.
But we can know,
after t2 end,
return 0;
ran.
But if we used join()
Here's the output:
THREAD 2!
THREAD 2!
THREAD 2!
...(THREAD 2!*10)
THREAD 1!
THREAD 1!
...(Always THREAD 1!)
Related
In my program I need to start 2 pieces of external hardware.
This is somewhat time consuming and I therefore want to run it in separate threads.
The start-up has two parts. The second part, hardwareTask2(), must be performed ca. simultaneously on both threads.
I therefore want to use a std::barrier to synchronize before calling this method.
However, the first part of the start-up, hardwareTask1() may fail.
If it fails on either thread I want both threads to return.
How do I achieve this?
Using std::barrier::arrive_and_drop() below I have managed to at least get the other thread to finish (not wait indefinitely at the barrier).
#include <iostream>
#include <thread>
#include <barrier>
bool hardwareTask1(unsigned int id) {
srand(id);
int r = rand() % 10;
std::this_thread::sleep_for(std::chrono::seconds(r));
return true;
}
// must be called ca. simultaneously:
void hardwareTask2() {
std::this_thread::sleep_for(std::chrono::seconds(5));
}
void startHardware(unsigned int id, std::barrier<>& b) {
bool ok = hardwareTask1(id);
// Simulate that the above function failed for the first thread:
if (id == 1) {
ok = false;
}
if (!ok) {
b.arrive_and_drop();
return;
}
std::cerr << id << ": finished task1\n";
b.arrive_and_wait();
std::cerr << id << ": after barrier\n";
hardwareTask2();
}
int main()
{
std::barrier<> b(2);
std::thread t1(&startHardware, 1, std::ref(b));
std::thread t2(&startHardware, 2, std::ref(b));
t1.join();
t2.join();
std::cerr << "Both threads have finished.\n";
int k;
std::cin >> k;
}
Like #UlrichEckhardt mentioned in his comment, you can use a std::future, std::promise pair to do the synchronization. Small example:
#include <iostream>
#include <future>
#include <random>
#include <thread>
void hardwareTask1(std::promise<bool> p)
{
std::cout << "HW 1: First part\n";
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(1, 10);
std::this_thread::sleep_for(std::chrono::seconds(distrib(gen)));
int res = distrib(gen);
if (res > 5) {
p.set_value(true);
std::cout << "HW 1: Second part\n";
}
else {
p.set_value(false);
std::cout << "HW 1: First part failed - abort\n";
}
}
void hardwareTask2(std::future<bool> f)
{
std::cout << "HW 2: First part\n";
if (f.get())
std::cout << "HW 2: Second part\n";
else
std::cout << "HW 2: HW 1 failed - abort\n";
}
int main()
{
std::promise<bool> p;
std::thread t2(&hardwareTask2, p.get_future());
std::thread t1(&hardwareTask1, std::move(p));
t1.join();
t2.join();
}
I was trying to understand the condition_variable available in C++ standard. So in the below test code I have written, I expect the func1 to be woken up after printing 50 numbers in main thread but here it prints all numbers only from main thread?
Could you please help me here to understand condition_variable better to indicate a certain thread to wake up
I have tried to understand condition variable using below code:
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
std::mutex mu;
std::condition_variable multiple;
bool isLoaded = false;
void func1()
{
std::unique_lock<std::mutex> unLock(mu);
multiple.wait(unLock, []() {return isLoaded; });
for (int i = 0; i < 100; i++)
{
cout << "This is from thread; " << i << endl;
}
}
int main()
{
std::thread t1(func1);
std::lock_guard<std::mutex> gaurd(mu);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
isLoaded = true;
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
You never release mu in main thread. Try something like this:
int main()
{
std::thread t1(func1);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
}
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
In general you need to keep your locks for absolute minimum of time you can.
You are taking mutex mu at start of your program and never let it go, so any other code under this mutex will never be executed.
Instead you should only hold it when you changing shared variables, something like:
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
multiple.notify_one();
}
I want to send a broadcast signal from the main thread to all the other threads waiting for a condition. It seems to me that the broadcast signal comes to early to the threads.
#include <iostream>
#include <pthread.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i){
lv1=i;
pthread_cond_broadcast(&cond);
}
};
cache c[NUM];
void *thread(void *arg){
int i = (int)arg;
for(;;){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
cout << "Thread: "<< i << endl;
//do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
pthread_barrier_init(&barrier,NULL,NUM+1);
for(int i=0;i<NUM;i++){
pthread_create(&tid[i],NULL,thread,(void*)i);
}
//Sleep(2);
c[0].write(55); //broadcast signal
//Sleep(2);
c[1].write(44); //broadcast signal
for(int i=0;i<NUM;i++){
pthread_join(tid[i],NULL);
}
cout << "Hello world!" << endl;
return 0;
}
If I insert Sleep(2) in the main function, it works, but I do not want to wait a time but a synchronisation before calling pthread_broadcast.
I thought of a barrier, but pthread_cond_wait is blocking, right?
You need to read up on how condition variables are used. You also handled the integer arguments to your threads erroneously. Here is a fixed version, hopefully similar to what you wanted:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i) { lv1=i; }
const int val() { return lv1; }
};
cache c[NUM];
void *thread(void *arg)
{
int i = *(int*)arg;
for(;;) {
pthread_mutex_lock(&mutex);
// Check predicate, do not go to sleep if predicate is fulfilled
if (c[0].val() > 0 && c[1].val() > 0) {
cout << "Thread " << i << " leaving...\n";
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_cond_wait(&cond, &mutex);
cout << "Thread wakeup: "<< i << endl;
// do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
int arg[NUM];
for(int i=0; i<NUM; i++) {
arg[i] = i; // make a copy of i used by only one thread
pthread_create(&tid[i], NULL, thread,(void*)&arg[i]);
}
pthread_mutex_lock(&mutex);
c[0].write(55);
c[1].write(44);
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond); // Signal all threads that predicate is fulfilled
for(int i=0; i<NUM; i++) {
pthread_join(tid[i],NULL);
cout << "Joined " << i << '\n';
}
cout << "Hello world!" << endl;
return 0;
}
Sequence how I think it is
This is how it is right now I think, I still need a way to synchronise, before I send the broadcast signal.
In that picture, the first pthread_broadcast comes too early.
I was trying to write code for Producer-Consumer problem. Below code works fine most of the time but stuck sometimes because of "Lost Wake-up" (i guess). I tried thread sleep() but it didn't work. What modification is needed to handle this case in my code? Is semaphore can be helpful here ? If yes, how will i implement them here ?
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace std;
int product = 0;
boost::mutex mutex;
boost::condition_variable cv;
boost::condition_variable pv;
bool done = false;
void consumer(){
while(done==false){
//cout << "start c" << endl
boost::mutex::scoped_lock lock(mutex);
cv.wait(lock);
//cout << "wakeup c" << endl;
if (done==false)
{
cout << product << endl;
//cout << "notify c" << endl;
pv.notify_one();
}
//cout << "end c" << endl;
}
}
void producer(){
for(int i=0;i<10;i++){
//cout << "start p" << endl;
boost::mutex::scoped_lock lock(mutex);
boost::this_thread::sleep(boost::posix_time::microseconds(50000));
++product;
//cout << "notify p" << endl;
cv.notify_one();
pv.wait(lock);
//cout << "wakeup p" << endl;
}
//cout << "end p" << endl;
cv.notify_one();
done = true;
}
int main()
{
int t = 1000;
while(t--){
/*
This is not perfect, and is prone to a subtle issue called the lost wakeup (for example, producer calls notify()
on the condition, but client hasn't really called wait() yet, then both will wait() indefinitely.)
*/
boost::thread consumerThread(&consumer);
boost::thread producerThread(&producer);
producerThread.join();
consumerThread.join();
done =false;
//cout << "process end" << endl;
}
cout << "done" << endl;
getchar();
return 0;
}
Yes, you want a way to know (in the consumer) that you "missed" a signal. A semaphore can help. There's more than one way to skin a cat, so here's my simple take on it (using just c++11 standard library features):
class semaphore
{
private:
std::mutex mtx;
std::condition_variable cv;
int count;
public:
semaphore(int count_ = 0) : count(count_) { }
void notify()
{
std::unique_lock<std::mutex> lck(mtx);
++count;
cv.notify_one();
}
void wait() { return wait([]{}); } // no-op action
template <typename F>
auto wait(F&& func = []{}) -> decltype(std::declval<F>()())
{
std::unique_lock<std::mutex> lck(mtx);
while(count == 0){
cv.wait(lck);
}
count--;
return func();
}
};
For convenience, I added a convenience wait() overload that takes a function to be executed under the lock. This makes it possible for the consumer to operate the 'semaphore' without ever manually operating the lock (and still get the value of product without data-races):
semaphore sem;
void consumer() {
do {
bool stop = false;
int received_product = sem.wait([&stop] { stop = done; return product; });
if (stop)
break;
std::cout << received_product << std::endl;
std::unique_lock<std::mutex> lock(processed_mutex);
processed_signal.notify_one();
} while(true);
}
A fully working demo: Live on Coliru:
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <cassert>
class semaphore
{
private:
std::mutex mtx;
std::condition_variable cv;
int count;
public:
semaphore(int count_ = 0) : count(count_) { }
void notify()
{
std::unique_lock<std::mutex> lck(mtx);
++count;
cv.notify_one();
}
void wait() { return wait([]{}); } // no-op action
template <typename F>
auto wait(F&& func = []{}) -> decltype(std::declval<F>()())
{
std::unique_lock<std::mutex> lck(mtx);
while(count == 0){
cv.wait(lck);
}
count--;
return func();
}
};
semaphore sem;
int product = 0;
std::mutex processed_mutex;
std::condition_variable processed_signal;
bool done = false;
void consumer(int check) {
do {
bool stop = false;
int received_product = sem.wait([&stop] { stop = done; return product; });
if (stop)
break;
std::cout << received_product << std::endl;
assert(++check == received_product);
std::unique_lock<std::mutex> lock(processed_mutex);
processed_signal.notify_one();
} while(true);
}
void producer() {
std::unique_lock<std::mutex> lock(processed_mutex);
for(int i = 0; i < 10; ++i) {
++product;
sem.notify();
processed_signal.wait(lock);
}
done = true;
sem.notify();
}
int main() {
int t = 1000;
while(t--) {
std::thread consumerThread(&consumer, product);
std::thread producerThread(&producer);
producerThread.join();
consumerThread.join();
done = false;
std::cout << "process end" << std::endl;
}
std::cout << "done" << std::endl;
}
You seems to ignore that the variable done is also a shared state, to the same extend as product. Which can lead to several races conditions. In your case, I see at least one scenario where consumerThread make no progress:
The loop execute has intended
consumer executes, and is waiting at cv.wait(lock);
producer has finished the for loop, and notify consumer and is preempted
consumer wakes up, read "done==false", output product, read done == false again, wait on the condition
producer set done to true and exit
consumer is stuck forever
To avoid these kind of issues you should be holding a lock when reading or writing done. Btw your implementation is quite sequential, ie the producer and the consumer can only process a single piece of data at the time...
I'm trying to implement a threaded object like this:
#include <pthread.h>
#include <iostream>
class Thread
{
private:
int id;
static void * run(void * arg)
{
int tid = (int)arg;
std::cout << "Thread " << tid << " executed." <<std::endl;
pthread_exit(NULL);
}
public:
Thread(int _id);
void start();
int get_id();
};
Here's the implementation of the public methods & constructor:
#include "std_thread.h"
Thread::Thread(int _id)
{
id = _id;
}
void Thread::start()
{
std::cout << "Thread created." <<std::endl;
pthread_t thread;
int rc = pthread_create(&thread, NULL, run, (void*)id);
if(rc)
std::cout << "Return code from thread is " << rc;
}
int Thread::get_id()
{
return id;
}
And here's main:
#include "std_thread.h"
int main()
{
Thread *thd = new Thread(0);
thd->start();
return 0;
}
When I create the thread object and call its start method, which is in turn supposed to print "Thread created." and run the thread body - it doesn't; actually, it does print Thread created to console, but doesn't seem to create a thread, or the thread just doesn't do anything. Everything compiles fine by the way, and there no run time errors.
Any ideas?
Your main returns before the thread gets a chance to run.
The program doesn't wait until all threads are done before exiting - once main is over, it's over, and the process is just shut down.
Have your pthread_t thread; as a member instead of a local variable, and add a method to wait for the thread to finish.
This is the simplest example I can come up with:
void Thread::wait()
{
pthread_join(thread, NULL);
}
int main()
{
Thread thd(0); // There's no point in using dynamic allocation here.
thd.start();
thd.wait();
return 0;
}