Multithreading beginner query (C++) - c++

I am trying to learn multithreading in C++. I am trying to pass elements of a vector as arguments to pthread_create. However, it is not working as expected.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <vector>
using namespace std;
void *count(void *arg)
{
int threadId = *((int *)arg);
cout << "Currently thread with id " << threadId << " is executing " << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t thread1;
vector<int> threadId(2);
threadId[0] = 99;
threadId[1] = 100;
int retVal = pthread_create(&thread1, NULL, count, (void *)&threadId[0]);
if (retVal)
{
cout << "Error in creating thread with Id: " << threadId[0] << endl;
exit(-1);
}
pthread_t thread2;
retVal = pthread_create(&thread2, NULL, count, (void *)&threadId[1]);
if (retVal)
{
cout << "Error in creating thread with Id: " << threadId[1] << endl;
exit(-1);
}
pthread_exit(NULL);
}
The output which I get is:
Currently thread with id 99 is executing.
Currently thread with id 0 is executing
However, according to me, it should be:
Currently thread with id 99 is executing.
Currently thread with id 100 is executing.
What am I missing here ?

int retVal = pthread_create(&thread1, NULL, count, (void *)&threadId[0]);
You have no guarantee, whatsoever, that the new execution thread is now running, right this very instant, without any delay.
All that pthread_create guarantees you is that the thread function, thread1, will begin executing at some point. It might be before pthread_create() itself returns. Or it might be at some point after. It's really a big mystery when the new thread function will start executing, but you can take it to the bank that the new execution thread will begin. Eventually.
The same thing goes for your 2nd execution thread.
So, both execution thread could very well get in gear after your main() returns, and after your vector gets destroyed. There's nothing in the shown code that guarantees that the execution threads will execute before the vector (whose contents get passed into them, in the manner shown) gets destroyed. And this leads to undefined behavior.
You will need to use other thread-related facilities that must be employed in order to synchronize multiple execution threads correctly. Additionally, you're using older POSIX threads. Modern C++ uses std::threads which offer many advantages over their predecessor, is completely type-safe (no ugly casts) and have numerous attributes that prevent common programming errors (however, in this instance std::threads also have no synchronization guarantee, this is usually the case with all typical execution thread implementations).

Related

Mutex does not work as expected

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.

Thread inside another thread in a while loop [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm pretty new to C++ and I'm experimenting with threads right now.
I'm trying to create a thread inside a thread under a while loop. But I don't think it seems to be working.
Presently my code looks like this:
#include <>
std::vector<pthread_t> outer_thread, inner_thread;
void *inner_thread(void *ptr)
{
string data1;
data1 = *(reinterpret_cast<string*>(ptr));
cout << "inner thread started " << data1;
/* do something */
cout << "inner thread stopped " << data1;
pthread_exit(NULL);
return 0;
}
void *outer_thread(void *ptr )
{
cout << "out thread started" << endl;
//cout << ptr << endl;
//cout << *(reinterpret_cast<string*>(ptr)) << endl;
string data;
data = *(reinterpret_cast<string*>(ptr));
string str3;
while (getline(data,str3))
{
cout << "out thread started" << endl;
pthread_t in_thread;
in_vec.push_back(str3);
int create_thread2 = pthread_create(&in_thread, NULL, &inner_thread, reinterpret_cast<void*>(&(in_vec.at(j))));
inner_thread.push_back(in_thread);
if (create_thread2 != 0)
cout << "Error : Thread";
j++;
cout << "out thread ends " << j << create_thread2 << endl ;
}
for (int k = 0; k < j ; k++)
{
pthread_join(inner_thread.at(k),NULL) ;
}
pthread_exit(NULL);
return 0;
}
int main (int argc, char *argv[])
{
int i = 0;
while (getline(gin,str))
{
string str1;
pthread_t out_thread;
cout << "str1" << str1 << endl;
now_vec.push_back(str1);
int create_thread = pthread_create(&out_thread, NULL, &outer_thread, reinterpret_cast<void*>(&(now_vec.at(i))));
outer_thread.push_back(out_thread);
if (create_thread != 0) cout << "Error : Thread" ;
i++;
}
for (int k = 0 ; k < i; k ++)
{
cout << i << endl;
//cout << "third thread " << outer_thread.at(1) << endl;
cout << outer_thread.at(k) << endl;
cout << "out out out" << endl;
pthread_join(outer_thread.at(k),NULL) ;
}
}
I'm trying to read a file which contains the list of files that should be read. I want to read all these files simultaneously.
All these files contain information and needs another set of threads to start another operation. So this also needs to be done simultaneously.
That's the reason I have 2 sets of threads running.
Let me know If there is any faster and simpler way to do this?
It seems to wait till the inner thread finishes and then starts with the next iteration. I want the inner threads to run simultaneously inside the outer thread. May I know how to go about this?
Your view of the operation of threads is wrong. A thread does not operate within another thread. They are independent streams of execution within the same process and their coexistence is flat, not hierarchical.
Some simple rules to follow when working with multiple threads:
Creating threads is expensive, so avoid creating and destroying them rapidly. It is best to create your threads once at the start of your application and assign them work to do as work becomes available.
When doing computational work, avoid creating more threads than can simultaneously execute on your CPU. Any additional threads will cause excess context switches and slow down your application.
Avoid the use of shared resources as often as possible, if a data structure must be shared between threads try and find a lock free implementation. If your shared resource is not available in a lock free implementation then use locks to protect it, but be very careful, improper use of locks can result in your application deadlocked or the performance of you application degrading to the serial execution case (as if there was only one thread).
In your particular case, if you want to speed up the processing of multiple files by processing them in parallel (and assuming the only task these threads need to achieve is the processing of these files), then a possible solution would look like:
Read in the list of files to operate on
Divide the list into sections (one section for each logical processor on you CPU).
Create your worker threads (one per logical processor) passing in their section of the file list (do not try to join with the thread in the same loop that creates it, this will block until the thread has finished executing causing your application to execute serially instead of in parallel, which is the case in the sample code you provided)
The worker threads can loop over their list of files, reading them one at a time and processing them.
In contrast to you proposed solution this one will not create a thread per file. Instead it will create as many threads as can run in parallel on your CPU avoiding the excessive context switching.
A primitive example of the above:
#include <pthread.h>
#include <vector>
#include <string>
#define NUM_THREADS 4
std::vector<std::string> work_pool[NUM_THREADS];
void *worker_thread(void *args);
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
// Read list of files here, distribute them evenly amongst the work_pools
for (int i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, worker_thread, (void *)i);
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
void *worker_thread(void *args)
{
const int id = (int)args;
std::vector<std::string>::iterator it;
for (it = work_pool[id].begin(); it != work_pool[id].end(); it++) {
// Read file and process it here
}
return NULL;
}
Not sure what you're trying to do, but among the many syntax errors that I hope come from simplying your code, this is what happens:
Main thread spawns a thread (1) and wait for it to finish (join)
(1) thread executes outer_thread and spawns another thread (2) and wait for it to finish (join)
(2) thread executes inner_thread and finish.
(2) gets joined and (1) thread is able to finish.
(1) gets joined and the main thread is able to go to the next iteration.
process starts again.
Note that you don't have any parallel execution, because your threads are waiting for other finish.
Note that throwing threads at a task is not the way to speed up.
Threads are a way of either:
Better using your CPU resources (when you have multiple CPU resources... and only using as many threads as CPU resources you have)
Simplifying the organization of your code by encapsulating requests as threads (but this kind of trick scale very badly)

Pthread and keyboard

I want to know how to run a thread to sleep some time every time I press a key. For example, if I press the same key twice, it should have two threads to sleep for a while.
I MUST use pthreads and C++.
Honestly I have tried many ways but I still do not know how to solve it.
Sorry if my english is not very good :)
UPDATE
This is my code:
#include <pthread.h>
#include <iostream>
#include <unistd.h>
using namespace std;
pthread_mutex_t mutex;
pthread_cond_t cond;
int a;
void* executer2(void*)
{
pthread_mutex_lock(&mutex);
while (a > 0) {
pthread_cond_wait(&cond, &mutex);
}
cout << "Thread: " << pthread_self() << endl;
sleep(a);
pthread_mutex_unlock(&mutex);
}
void* executer(void*)
{
int key;
while (1) {
pthread_mutex_lock(&mutex);
key = cin.get();
if (key == 'a') {
cout << "Sleep for 4 seconds" << endl;
a = 4;
} else if (key == 'b') {
cout << "Sleep for 8 seconds" << endl;
a = 8;
} else {
cout << "Sleep for 2 seconds" << endl;
a = 2;
}
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main()
{
pthread_t tr, t;
pthread_attr_t attr;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&tr, &attr, executer, NULL);
pthread_create(&t, &attr, executer2, NULL);
pthread_join(tr, NULL);
pthread_join(t, NULL);
}
since you want to create a thread each time you press a key, and that the keypress handler is in executer, you should move the code to create executer2 in executer.
executer is made to sleep 1 sec. after reading a key press, but it seems that's not what you want. Just remove that call to sleep(1) to get an immediate response
the code of executer seems to indicate that you wish to modulate the time spent sleeping by the thread depending on the input key. You can pass the sleep time as a parameter to executer2, as indicated by the void * parameter of that function. The idea is to cast the time value to a void *, pass it at thread creation time, and cast it back to int within executer2:
// executer2 thread creation
pthread_create(&t, &attr, executer2,(void *)a);
and in executer2:
void *executer2(void *arg){
int a = (int)arg;
// ...
The thread creation code should go after the switch in executer2, and you should not need the global a variable anymore.
you are currently using a mutex to lock the code of executer2. This will prevent all the sleeping threads to sleep together at the same time. You will have to remove the lock to allow them to sleep concurrently (but leave the lock around the text output).
you say that you wish a C++ solution. You could benefit from using the thread library from the stl, which wraps the OS thread primitives (pthreads in your case) with higher level constructs and are easier to manipulate, especially for parameters. It would be a good exercise to convert your programme to use this library once you have the current code working.

return() versus pthread_exit() in pthread start functions

The following program shows that we can use return or pthread_exit to return a void* variable that is available to pthread_join's status variable.
Should there be a preference for using one over the other?
Why does using return work? Normally we think of return putting a value on the stack but since the thread is completed the stack should vanish. Or does the stack not get destroyed until after pthread_join?
In your work, do you see much use of the status variable? It seems 90% of the code I see just NULLs out the status parameter. Since anything changed via the void* ptr is already reflected in the calling thread there doesn't seem much point to returning it. Any new void* ptr returned would have to point to something malloced by the start thread, which leaves the receiving thread with the responsibility to dispose of it. Am I wrong in thinking the status variable is semi-pointless?
Here is the code:
#include <iostream>
#include <pthread.h>
using namespace std;
struct taskdata
{
int x;
float y;
string z;
};
void* task1(void *data)
{
taskdata *t = (taskdata *) data;
t->x += 25;
t->y -= 4.5;
t->z = "Goodbye";
return(data);
}
void* task2(void *data)
{
taskdata *t = (taskdata *) data;
t->x -= 25;
t->y += 4.5;
t->z = "World";
pthread_exit(data);
}
int main(int argc, char *argv[])
{
pthread_t threadID;
taskdata t = {10, 10.0, "Hello"};
void *status;
cout << "before " << t.x << " " << t.y << " " << t.z << endl;
//by return()
pthread_create(&threadID, NULL, task1, (void *) &t);
pthread_join(threadID, &status);
taskdata *ts = (taskdata *) status;
cout << "after task1 " << ts->x << " " << ts->y << " " << ts->z << endl;
//by pthread_exit()
pthread_create(&threadID, NULL, task2, (void *) &t);
pthread_join(threadID, &status);
ts = (taskdata *) status;
cout << "after task2 " << ts->x << " " << ts->y << " " << ts->z << endl;
}
With output of:
before 10 10 Hello
after task1 35 5.5 Goodbye
after task2 10 10 World
(1) In C++ code, using return causes the stack to be unwound and local variables destroyed, whereas pthread_exit is only guaranteed to invoke cancellation handlers registered with pthread_cancel_push(). On some systems this mechanism will also cause the destructors for C++ local variables to be called, but this is not guaranteed for portable code --- check your platform documentation.
Also, in main(), return will implicitly call exit(), and thus terminate the program, whereas pthread_exit() will merely terminate the thread, and the program will remain running until all threads have terminated or some thread calls exit(), abort() or another function that terminates the program.
(2) The use of return works because the POSIX specification says so. The returned value is stored in a place where pthread_join() can retrieve it. The resources used by the thread are not reclaimed until pthread_join() is called.
(3) I never use the return value of a thread in raw POSIX threads. However, I tend to use higher level facilities such as the Boost thread library, and more recently the C++0x thread library, which provide alternative means for transferring values between threads such as futures, which avoid the problems associated with memory management that you allude to.
I think that return from the start_routine is preferable, because it ensures that the call stack is properly unwound.
This is even more important for C than C++ since it doesn't have the destructor magic that cleans up the mess after preliminary exits. So your code should go through all final parts of routines on the call stack to do frees and alike.
For why this works, this is simple
If the start_routine returns, the effect shall be as if there was an
implicit call to pthread_exit() using the return value of
start_routine as the exit status
For my personal experience I tend to not use the status of terminated threads much. This is why I often have the threads started detached. But this should depend much on the application and is certainly not generalizable.

Bizarre thread printing behaviour

Hey - I'm having an odd problem with a little toy program I've written, to try out threads.
This is my code:
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;
void *threadFunc(void *arg) {
cout << "I am a thread. Hear me roar." << endl;
pthread_exit(NULL);
}
int main() {
cout << "Hello there." << endl;
int returnValue;
pthread_t myThread;
returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);
if (returnValue != 0) {
cout << "Couldn't create thread! Whoops." << endl;
return -1;
}
return 0;
}
With the first cout in main not commented out, the thread prints fine.
However, without it, the thread doesn't print anything at all.
Any help?
Try this:
#include <pthread.h>
#include <iostream>
using std::cout;
using std::endl;
void *threadFunc(void *arg) {
cout << "I am a thread. Hear me roar." << endl;
pthread_exit(NULL);
}
int main() {
//cout << "Hello there." << endl;
int returnValue;
pthread_t myThread;
returnValue = pthread_create(&myThread, NULL, threadFunc, NULL);
if (returnValue != 0) {
cout << "Couldn't create thread! Whoops." << endl;
return -1;
}
pthread_join( myThread, NULL);
return 0;
}
The difference between my code and yours is one line - pthread join. This suspends the main thread until the sub-thread has had chance to complete its actions.
In your code, execution reaches the first cout and it's processed. Then, you split off another thread and the main thread carries on until the end, which may or may not be reached before the secondary thread is tidied up. That's where the odd behaviour comes in - what you are experiencing is the case where the main program finishes before the sub-thread has had a chance to, so the program has "returned" and the whole lot is cleaned up by the kernel.
It's a race condition that allows the program to work when the main loop takes a little while to run. Your program is exiting before the thread even has a chance to run.
You should wait for the thread to complete (see pthread_join) before returning from main().
The fact that it works in one case is pure luck. You have a timing issue, which is your program is exiting before your thread does it's work.
When main() exits all your threads will die. You need some sort of waiting in place to give the other thread time to run before main() exits. Try adding a cin in main() after you create the worker thread and see what happens.
Ultimately you'll want some sort of run-loop and messaging/eventing to communicate between threads.
-jeff
Try adding a pthread_exit(NULL); at the end of main, before the return 0. I suspect that the problem is your main returns and the process exits before the thread has a chance to print. Printing from main might be somehow modifying the timing such that the thread does get a chance to print -- but that's is just sheer luck. You need to ensure that main doesn't return until all of your threads are finished doing their work. Calling pthread_exit from main allows other threads to continue running until they too have called pthread_exit.