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)
Related
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).
I don't really know much about threads in c++. Here is a simple code:
int a = 0;
int main()
{
std::thread t1([=]() {
for (int i = 0; i < 10; i++)
{
a += 1;
std::cout << "A in another thread: " << a << std::endl;
}
});
for (int i = 0; i < 10; i++)
{
a += 1;
std::cout << "A in main: " << a << std::endl;
}
}
When I run this code it gives me a Debug Error: abort() has been called.
How can I change a global variable's value on multiple threads?
because you didn't joined thread after your programme finished. OS will send SIGABRT to detached thread to avoid this problem you should join the thread.
you should put below line at end of main:
t1.join()
Note: beware about possible race condition on variable a.
You have 2 issues:
First of all when you start another thread you have to join it or detach before the program terminates.
Second thing is that you can read the same variable from many threads, but writing to it creates race condition.
I'm trying to turn a code from a single thread to a multi thread(example, create 6 threads instead of 1) while making sure they all start and finish without any interference from each other. What would be a way to do this? Could I just do a for loop that creates a thread until i < 6? And just add a mutex class with lock() and unlock()?
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
void workerFunc()
{
boost::posix_time::seconds workTime(3);
std::cout << "Worker: running" << std::endl;
// Pretend to do something useful...
boost::this_thread::sleep(workTime);
std::cout << "Worker: finished" << std::endl;
}
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc);
std::cout << "main: waiting for thread" << std::endl;
workerThread.join();
std::cout << "main: done" << std::endl;
system("pause");
return 0;
}
Yes, it's certainly possible. Since you don't want any interference between them, give them unique data to work with so that you do not need to synchronize the access to that data with a std::mutex or making it std::atomic. To further minimize the interference between threads, align the data according to std::hardware_destructive_interference_size.
You can use boost::thread::hardware_concurrency() to get the number of hardware threads available on the current system so that you don't have to hardcode the number of threads to run.
Passing references to the thread can be done using std::ref (or else the thread will get a ref to a copy of the data).
Here I create a std::list of threads and a std::vector of data to work on.
#include <cstdint> // std::int64_t
#include <iostream>
#include <list>
#include <new> // std::hardware_destructive_interference_size
#include <vector>
#include <boost/thread.hpp>
unsigned hardware_concurrency() {
unsigned rv = boost::thread::hardware_concurrency();
if(rv == 0) rv = 1; // fallback if hardware_concurrency returned 0
return rv;
}
// if you don't have hardware_destructive_interference_size, use something like this
// instead:
//struct alignas(64) data {
struct alignas(std::hardware_destructive_interference_size) data {
std::int64_t x;
};
void workerFunc(data& d) {
// work on the supplied data
for(int i = 0; i < 1024*1024-1; ++i) d.x -= i;
for(int i = 0; i < 1024*1024*1024-1; ++i) d.x += i;
}
int main() {
std::cout << "main: startup" << std::endl;
size_t number_of_threads = hardware_concurrency();
std::list<boost::thread> threads;
std::vector<data> dataset(number_of_threads);
// create the threads
for(size_t idx = 0; idx < number_of_threads; ++idx)
threads.emplace_back(workerFunc, std::ref(dataset[idx]));
std::cout << "main: waiting for threads" << std::endl;
// join all threads
for(auto& th : threads) th.join();
// display results
for(const data& d : dataset) std::cout << d.x << "\n";
std::cout << "main: done" << std::endl;
}
If you are using C++11 (or later), I suggest using std::thread instead.
Starting and stopping a bunch of Boost threads
std::vector<boost::thread> threads;
for (int i = 0; i < numberOfThreads; ++i) {
boost::thread t(workerFunc);
threads.push_back(std::move(t));
}
for (auto& t : threads) {
t.join();
}
Keep in mind that join() doesn't terminate the threads, it only waits until they are finished.
Synchronization
Mutexes are required if multiple threads access the same data and at least one of them is writing the data. You can use a mutex to ensure that multiple threads enter the critical sections of the code. Example:
std::queue<int> q;
std::mutex q_mu;
void workerFunc1() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
q.push(foo);
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
void workerFunc2() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
foo = q.pop();
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
This prevents undefined behavior like reading an item from the queue that hasn't been written completely. Be careful - data races can crash your program or corrupt your data. I'm frequently using tools like Thread Sanitizer or Helgrind to ensure I didn't miss anything. If you only want to pass results back into the main program but don't need to share data between your threads you might want to consider using std::promise and std::future.
Yes, spawning new threads can be done with a simple loop. You will have to keep a few things in mind though:
If threads will operate on shared data, it will need to be protected with mutexes, atomics or via some other way to avoid data races and undefined behaviour (bear in mind that even primitive types such as int have to be wrapped with an atomic or mutex according to the standard).
You will have to make sure that you will eventually either call join() or detach() on every spawned thread before its object goes out of scope to prevent it from suddenly terminating.
Its best to do some computations on the main thread while waiting for worker threads to use this time efficiently instead of wasting it.
You generally want to spawn 1 thread less than the number of total threads you want as the program starts running with with one thread by default (the main thread).
Hi for beginning I want to say that I'm new in this stuff so sorry for this basic question.
#include <SFML/System.hpp>
#include <iostream>
void func()
{
// this function is started when thread.launch() is called
for (int i = 0; i < 10; ++i)
std::cout << "I'm thread number one" << std::endl;
}
int main()
{
// create a thread with func() as entry point
sf::Thread thread(&func);
// run it
thread.launch();
// the main thread continues to run...
for (int i = 0; i < 10; ++i)
std::cout << "I'm the main thread" << std::endl;
return 0;
}
this is code from sfml offical site and it should be printing:
I'm thread number one
I'm the main thread
I'm the main thread
I'm thread number one
I'm thread number one
etc but console print first 10x times "I'm thread number one" and the the second one and i have no idea why. I used this tutorial to install sfml https://youtu.be/axIgxBQVBg0 .
The example from SFML's website is an example of potential output. If you notice the output given in that example seems a little unpredictable that is because it is. You are extremely unlikely to reproduce it. As noted in the comments you won't have explicit control over the threads without further synchronization.
I have been reading over the following tutorial: C++ Multithreading Tutorial.
I have compiled the code in the tutorial that creates ten unique threads and print a string with the thread number.
Here is what the code looks like for those who don't want to open the link:
#include <iostream>
#include <thread>
static const int num_threads = 10;
//This function will be called from a thread
void call_from_thread(int tid) {
std::cout << "Launched by thread " << tid << std::endl;
}
int main() {
std::thread t[num_threads];
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
std::cout << "Launched from the main\n";
//Join the threads with the main thread
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
return 0;
}
When I run the code it compiles and the output is kind of random.
It will launch each thread but it won't launch them in order.
I was reading the C++ reference on std::mutex and it sounds like that is what I need.
So, I was wondering if someone could give me a quick rundown over how to implement std:mutex in code like this to ensure that the threads don't use the same shared resource and to ensure that they launch in order.
The threads are created in the right order, but the order of scheduling of their execution is not guaranteed to be the same.
Is mutex the solution ?
You could attempt to add a mutex. This will only assure that two threads are not in the critical section at the same time:
std::mutex mtx;
void call_from_thread(int tid) {
std::lock_guard<std::mutex> lock(mtx); // holds the lock until scope is left
std::cout << "Launched by thread " << tid << std::endl;
}
Note tha I didn't lock the mutex directly and I prefered the lock_guard: this locks the mutex using RAII which is exception safe.
Online demo 1
Is atomic the solution
Another way to do multithreading without mutex, is to use atomic variables. These are guaranteed to be accessed by one thread at a time without data race.
std::atomic<int> cnt{0};
void call_from_thread(int tid) {
while (cnt!=tid)
std::this_thread::yield();
std::cout << "Launched by thread " << tid << std::endl;
cnt++;
}
Of course the code above is useless: it just makes sure that threads are executed in sequence. Every thread looks it the global atomic counter corresponds to its number. if yes, it executes and increments the global counter. If not, it just gives the opportunity to another thread to execute.
Online demo 2
Of course this construct here is a waste of time. Normally, you'd use condition variables to do something like this. it's only for illustration.
Conclusion
Multithreading is quite complex. If you want to dig into it, I highly recommend Anthony William's book "C++ Concurrency in action", which is an excellent step by step introduction, not only to C++ multithreading libraries, but more generally challenges of multithreaded algorithms.