I have written a simple thread pool in c++ using posix, on Ubuntu, which compiles and runs as expected, when started from within Code::Blocks. However, when I execute the program from the terminal, it hangs after the first thread task completes.
Here is the code in the execute() function of the task object:
void TestTask::execute()
{
FILE* file;
std::string fname = "output";
char n = (char)m_id;
fname+=n;
fname+=".txt";
file = fopen(fname.c_str(), "w");
for (int i = 0; i < 10; i++)
{
fprintf(file,"Thread ID: %d, count : %d\n", m_id, i);
}
fclose(file);
}
As you can see, the code simply outputs some data to a seperate file for each thread.
I have also tried:
void TestTask::execute()
{
for (int i = 0; i < 10; i++)
{
printf("Thread ID: %d, count : %d\n", m_id, i);
}
}
As previously stated, both of these versions work perfectly when the project is built and run in code::blocks, but when the executable is run from a command line, it hangs.
Thread pool code:
ThreadPool::ThreadPool(int iNumThreads):mRunning(false), mShuttingDown(false)
{
mThreads.resize(iNumThreads);
if(iNumThreads > 0)
for (int i = 0; i < iNumThreads; i++)
{
pthread_create(&mThreads[i], NULL, ThreadPool::ThreadFunc,(void*) this);
}
pthread_mutex_init(&mMemLock, NULL); //mutex' are initialised unlocked.
}
void ThreadPool::stop()
{
pthread_mutex_lock(&mMemLock);
mRunning = false;
pthread_mutex_unlock(&mMemLock);
}
void ThreadPool::start()
{
//signal all threads to wake up and start extracting tasks to execute.
if(!mTasks.empty())
pthread_cond_broadcast(&mConditionSignal);
mRunning = true;
}
bool ThreadPool::shutDown()
{
//terminate all threads, regardless of status. Brute force approach, only to be used in race conditions or major errors.
for (size_t i = 0; i < mThreads.size();i++)
{
int err = pthread_cancel(mThreads[i]);
if(err != 0)
return false;
}
return true;
}
bool ThreadPool::shutDownClean()
{
//set flag and wait for all threads to terminate normally
mShuttingDown = true;
for(size_t i = 0; i < mThreads.size();i++)
{
pthread_join(mThreads[i], NULL);
}
return true;
}
bool ThreadPool::addTask(Task* pTask, bool start)
{
mTasks.push_back(pTask);
if(start)
{
mRunning = true;
pthread_cond_signal(&mConditionSignal);
}
return true;
//wake up a single thread to deal with a single task (first come, first served)
}
void ThreadPool::addCompleteTask(Task* pTask)
{
mCompletedTasks.push_back(pTask);
}
Task* ThreadPool::getNextCompletedTask()
{
Task* t = mCompletedTasks.front();
mCompletedTasks.pop_front();
return t;
}
Task* ThreadPool::getNextScheduledTask()
{
Task* t = mTasks.front();
mTasks.pop_front();
return t;
}
bool ThreadPool::isRunning()
{
return (mRunning);
}
ThreadPool::~ThreadPool()
{
if(!mShuttingDown)
shutDownClean();
mThreads.clear();
mTasks.clear();
mCompletedTasks.clear();
}
void* ThreadPool::ThreadFunc(void* ptr)
{
ThreadPool *pool = (ThreadPool*)ptr;
Task *task;
//infinite do nothing loop. The thread will spin it's wheels while it waits for work.
while(true)
{
pthread_mutex_lock(&pool->getMutex());
while(pool->isRunning() && !pool->hasCurrentTasks())
{
//wait on signal from pool to begin
pthread_cond_wait(&pool->getCondition(), &pool->getMutex());
}
//If the pool has tasks needing executed
if(pool->hasCurrentTasks())
{
//get the task and execute it, after unlocking the mutex
task = pool->getNextScheduledTask();
pthread_mutex_unlock(&pool->getMutex());
task->execute();
//if the task has return data, then add it to the list of completed tasks, for the main thread to evaluate
if(task->hasReturnData())
{
pthread_mutex_lock(&pool->getMutex());
pool->addCompleteTask(task);
pthread_mutex_unlock(&pool->getMutex());
}
//if not, we need not keep the task object any more
else
delete task;
}
else
{
//stop the pool running, and unlock the mutex
pool->stop();
pthread_mutex_unlock(&pool->getMutex());
}
if(pool->isShuttingDown())
{
break;
}
}
pthread_exit(NULL);
}
Here is the code from main.cpp:
int main(int argc, char** argv)
{
int numCores = sysconf(_SC_NPROCESSORS_ONLN);
ThreadPool* pool = new ThreadPool(numCores);
for (int i = 0; i < numCores; i++)
{
if(!pool->addTask(new TestTask(i)))
pool->shutDown();
}
pool->start();
if(!pool->shutDownClean())
return 1;
else
return 0;
}
Related
Here i defined the handles and task prototypes
void Task1(void *p);
void Task2(void *p);
TaskHandle_t Task1_handle;
TaskHandle_t Task2_handle;
SemaphoreHandle_t myMutex;
Here is the setup function with the task and mutex creation functions
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myMutex = xSemaphoreCreateMutex();
if(myMutex == NULL)
{
Serial.println("Mutex cannot be created");
}
xTaskCreate(Task1, "Task 1", 100, NULL, 1, &Task1_handle);
xTaskCreate(Task2, "Task 2", 100, NULL, 1, &Task2_handle);
vTaskStartScheduler();
}
void loop() {
// put your main code here, to run repeatedly:
}
Here are the tasks i created
void Task1(void *p)
{
(void) p;
while(1)
{
xSemaphoreTake(myMutex, portMAX_DELAY);
Serial.println("task 1");
for(int i = 0; i < 5; i++)
{
Serial.println(i);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
xSemaphoreGive(myMutex);
}
}
void Task2(void *p)
{
(void) p;
while(1)
{
xSemaphoreTake(myMutex, portMAX_DELAY);
Serial.println("task 2");
for(int i = 0; i < 5; i++)
{
Serial.println(i);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
xSemaphoreGive(myMutex);
}
}
This is my code so far, but i dont seem to be getting my second task on the serial monitor:
Serial Monitor Output
Am i using the semaphore function wrong?
The mutex is locked while the Task 1 is sleeping, so Task 2 can never get the mutex. The section that is guarded by the mutex should be as short as possible, for example:
void Task1(void *p)
{
(void)p;
while (1) {
xSemaphoreTake(myMutex, portMAX_DELAY);
Serial.println("task 1");
xSemaphoreGive(myMutex);
for (int i = 0; i < 5; i++) {
xSemaphoreTake(myMutex, portMAX_DELAY);
Serial.println(i);
xSemaphoreGive(myMutex);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
}
Modify the Task 2 in the same way.
Hello I want to sync two threads one incrementing a variable and other decrementing it.
The result that I want looks like:
Thread #0 j = 1
Thread #1 j = 0
Thread #0 j = 1
Thread #1 j = 0
And so on.. but my code sometimes works like that in some cases it print really weird values. I supose that I have some undefined behavior in somewhere but I can't figured out what is really happen.
My code consist in a HANDLE ghMutex that containg the handler of my mutex:
My main function:
int main(void)
{
HANDLE aThread[THREADCOUNT];
ghMutex = CreateMutex(NULL, FALSE, NULL);
aThread[0] = (HANDLE)_beginthreadex(NULL, 0, &inc, NULL, CREATE_SUSPENDED, 0);
aThread[1] = (HANDLE)_beginthreadex(NULL, 0, &dec, NULL, CREATE_SUSPENDED, 0);
ResumeThread(aThread[0]);
ResumeThread(aThread[1]);
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
printf("j = %d\n", j);
for (int i = 0; i < THREADCOUNT; i++)
CloseHandle(aThread[i]);
CloseHandle(ghMutex);
return 0;
}
Inc function:
unsigned int __stdcall inc(LPVOID)
{
for (volatile int i = 0; i < MAX; ++i)
{
WaitForSingleObject(
ghMutex, // handle to mutex
INFINITE); // no time-out interval
j++;
printf("Thread %d j = %d\n", GetCurrentThreadId(), j);
ReleaseMutex(ghMutex);
}
_endthread();
return TRUE;
}
Dec function:
unsigned int __stdcall dec(void*)
{
for (volatile int i = 0; i < MAX; ++i)
{
WaitForSingleObject(
ghMutex, // handle to mutex
INFINITE); // no time-out interval
j--;
printf("Thread %d j = %d\n", GetCurrentThreadId(), j);
ReleaseMutex(ghMutex);
}
_endthread();
return TRUE;
}
I need a win api solution in std c++98.
A mutex is not the right tool to synchronize two threads, it is there to protect a resource. You do have a resource j which is protected by your mutex, however the sequence of which thread gets the lock is undefined, so you can have the case where dec gets called several times before inc has the chance to run.
If you want to synchronize the order of the threads you will have to use another synchronization primitive, for example a semaphore. You could, for example, increment the semaphore in inc and decrement it in dec. This would be the classic producer - consumer relationship where the producer will be stalled when the semaphore reaches its maximum value and the consumer will wait for items to consume.
Sorry, no WinAPI C++98 solution from me because that would be silly, but I hope I pointed you to the right direction.
windows mutex object guarantees exclusive ownership, but does not care about the ownership order. so that the same thread can capture several times in a row while others will wait.
for your task you need signal to another thread, when your task is done, and then wait for signal from another thread. for this task can be used event pair for example. thread (i) signal event (1-i) and wait on event (i). for optimize instead 2 calls -
SetEvent(e[1-i]); WaitForSingleObject(e[i], INFINITE);
we can use single call SignalObjectAndWait
SignalObjectAndWait(e[1-i], e[i], INFINITE, FALSE)
of course start and end of loop require special care. for inc
HANDLE hObjectToSignal = _hEvent[1], hObjectToWaitOn = _hEvent[0];
for (;;)
{
_shared_value++;
if (!--n)
{
SetEvent(hObjectToSignal);
break;
}
SignalObjectAndWait(hObjectToSignal, hObjectToWaitOn, INFINITE, FALSE);
}
and for dec
HANDLE hObjectToSignal = _hEvent[0], hObjectToWaitOn = _hEvent[1];
WaitForSingleObject(hObjectToWaitOn, INFINITE);
for (;;)
{
--_shared_value;
if (!--n)
{
break;
}
SignalObjectAndWait(hObjectToSignal, hObjectToWaitOn, INFINITE, FALSE);
}
if write full test, with error checking
struct Task
{
HANDLE _hEvent[4];
ULONG _n;
LONG _iTasks;
LONG _shared_value;
Task()
{
RtlZeroMemory(this, sizeof(*this));
}
~Task()
{
ULONG n = RTL_NUMBER_OF(_hEvent);
do
{
if (HANDLE hEvent = _hEvent[--n]) CloseHandle(hEvent);
} while (n);
}
ULONG WaitTaskEnd()
{
return WaitForSingleObject(_hEvent[2], INFINITE);
}
ULONG WaitTaskReady()
{
return WaitForSingleObject(_hEvent[3], INFINITE);
}
void SetTaskReady()
{
SetEvent(_hEvent[3]);
}
void End()
{
if (!InterlockedDecrement(&_iTasks)) SetEvent(_hEvent[2]);
}
void Begin()
{
InterlockedIncrementNoFence(&_iTasks);
}
static ULONG WINAPI IncThread(PVOID p)
{
return reinterpret_cast<Task*>(p)->Inc(), 0;
}
void Inc()
{
if (WaitTaskReady() == WAIT_OBJECT_0)
{
if (ULONG n = _n)
{
HANDLE hObjectToSignal = _hEvent[1], hObjectToWaitOn = _hEvent[0];
for (;;)
{
if (_shared_value) __debugbreak();
if (n < 17) DbgPrint("Inc(%u)\n", n);
_shared_value++;
if (!--n)
{
SetEvent(hObjectToSignal);
break;
}
if (SignalObjectAndWait(hObjectToSignal, hObjectToWaitOn, INFINITE, FALSE) != WAIT_OBJECT_0)
{
break;
}
}
}
}
End();
}
static ULONG WINAPI DecThread(PVOID p)
{
return reinterpret_cast<Task*>(p)->Dec(), 0;
}
void Dec()
{
if (WaitTaskReady() == WAIT_OBJECT_0)
{
if (ULONG n = _n)
{
HANDLE hObjectToSignal = _hEvent[0], hObjectToWaitOn = _hEvent[1];
if (WaitForSingleObject(hObjectToWaitOn, INFINITE) == WAIT_OBJECT_0)
{
for (;;)
{
--_shared_value;
if (_shared_value) __debugbreak();
if (n < 17) DbgPrint("Dec(%u)\n", n);
if (!--n)
{
break;
}
if (SignalObjectAndWait(hObjectToSignal, hObjectToWaitOn, INFINITE, FALSE) != WAIT_OBJECT_0)
{
break;
}
}
}
}
}
End();
}
ULONG Create()
{
ULONG n = RTL_NUMBER_OF(_hEvent);
do
{
if (HANDLE hEvent = CreateEventW(0, n > 2, 0, 0)) _hEvent[--n] = hEvent;
else return GetLastError();
} while (n);
return NOERROR;
}
ULONG Start()
{
static PTHREAD_START_ROUTINE aa[] = { IncThread, DecThread };
ULONG n = RTL_NUMBER_OF(aa);
do
{
Begin();
if (HANDLE hThread = CreateThread(0, 0, aa[--n], this, 0, 0))
{
CloseHandle(hThread);
}
else
{
n = GetLastError();
End();
return n;
}
} while (n);
return NOERROR;
}
ULONG Start(ULONG n)
{
_iTasks = 1;
ULONG dwError = Start();
_n = dwError ? 0 : n;
SetTaskReady();
End();
return dwError;
}
};
void TaskTest(ULONG n)
{
Task task;
if (task.Create() == NOERROR)
{
task.Start(n);
task.WaitTaskEnd();
}
}
note, that no any sense declare local variable (which will be accessed only from single thread and not accessed by any interrupts, etc) as volatile
also when we write code, like:
// thread #1
write_shared_data();
SetEvent(hEvent);
// thread #2
WaitForSingleObject(hEvent, INFINITE);
read_shared_data();
inside SetEvent(hEvent); was atomic write to event state with release semantic (really stronger of course) and inside wait for event function - atomic read it state with more than acquire semantic. as result all what thread #1 write to memory before SetEvent - will be visible to thread #2 after Wait for event (if wait finished as result of call Set from thread #1)
I am new to multithreading and i need your help.
Consider the following code:
vector <int> vec;
int j = 0;
void Fill()
{
for (int i = 0; i < 500; i++)
{
Sleep(500);
vec.push_back(i);
}
}
void Proces()
{
int count = 0;
int n=-1;
while (true) {
Sleep(250);
if (!vec.empty())
{
if (n != vec.back()) {
n = vec.back();
cout << n;
count++;
}
}
if (count == 101)break;
}
}
void getinput()
{
while (true) {
int k=0;
cin >> k;
//if the user enters an integer i want to kill all the threads
}
}
int main()
{
thread t1(Fill);
thread t2(Proces);
thread t3(getinput);
t1.join();
t2.join();
t3.join();
cout << "From main()";
}
The point is that i want to kill t1(Fill) and t2(Proces) from t3(getinput).Is there and way to do it,and if there is could you please post and example.
A common way to make a thread exit is to have an (atomic) flag that the thread checks to see if it should exit. Then externally you set this flag and the thread will notice it and exit naturally.
Something like
#include <thread>
#include <atomic>
#include <iostream>
#include <chrono>
// Flag telling the thread to continue or exit
std::atomic<bool> exit_thread_flag{false};
void thread_function()
{
// Loop while flag if not set
while (!exit_thread_flag)
{
std::cout << "Hello from thread\n";
std::this_thread::sleep_for(std::chrono::seconds(1)); // Sleep for one second
}
}
int main()
{
std::thread t{thread_function}; // Create and start the thread
std::this_thread::sleep_for(std::chrono::seconds(5)); // Sleep for five seconds
exit_thread_flag = true; // Tell thread to exit
t.join(); // Wait for thread to exit
}
You have to define an exit condition and lock the container before accessing it. Of course you could build an own collection as wrapper around an existing using proper locking and thus making it thread-safe.
Here is an example of locking and an exit condition:
class Test
{
public:
Test()
: exitCondition(false)
{
work = std::thread([this]() { DoWork(); });
}
~Test()
{
if (work.joinable())
work.join();
}
void Add(int i)
{
mutex.lock();
things.push_back(i);
mutex.unlock();
}
void RequestStop(bool waitForExit = false)
{
exitCondition.exchange(true);
if (waitForExit)
work.join();
}
private:
void DoWork()
{
while (!exitCondition)
{
mutex.lock();
if (!things.empty())
{
for (auto itr = things.begin(); itr != things.end();)
itr = things.erase(itr);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
mutex.unlock();
}
}
private:
std::vector<int> things;
std::thread work;
std::atomic<bool> exitCondition;
std::mutex mutex;
};
int wmain(int, wchar_t**)
{
Test t;
t.Add(1);
t.Add(2);
t.Add(3);
t.RequestStop(true);
return 0;
}
std::atomic<bool> exit_flag{false};
...
void Fill() {
for (int i = 0; i < 500; i++) {
if (exit_flag) return;
...
}
}
void Proces() {
while (true) {
if (exit_flag) return;
...
}
}
void getinput() {
while (true) {
...
if ( /* the user enters an integer i want to kill all the threads */ )
exit_flag = true;
}
}
I have experience with threads in Java but want to learn how to use them in C++11. I tried to make a simple threadpool, where threads are created once and can be asked to execute tasks.
#include <thread>
#include <iostream>
#define NUM_THREADS 2
class Worker
{
public:
Worker(): m_running(false), m_hasData(false)
{
};
~Worker() {};
void execute()
{
m_running = true;
while(m_running)
{
if(m_hasData)
{
m_system();
}
m_hasData = false;
}
};
void stop()
{
m_running = false;
};
void setSystem(const std::function<void()>& system)
{
m_system = system;
m_hasData = true;
};
bool isIdle() const
{
return !m_hasData;
};
private:
bool m_running;
std::function<void()> m_system;
bool m_hasData;
};
class ThreadPool
{
public:
ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
m_threads[i] = std::thread(&Worker::execute, &m_workers[i]);
}
};
~ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
std::cout << "Stopping " << i << std::endl;
m_workers[i].stop();
m_threads[i].join();
}
};
void execute(const std::function<void()>& system)
{
// Finds the first non-idle worker - not really great but just for testing
for(int i = 0; i < NUM_THREADS; ++i)
{
if(m_workers[i].isIdle())
{
m_workers[i].setSystem(system);
return;
}
}
};
private:
Worker m_workers[NUM_THREADS];
std::thread m_threads[NUM_THREADS];
};
void print(void* in, void* out)
{
char** in_c = (char**)in;
printf("%s\n", *in_c);
}
int main(int argc, const char * argv[]) {
ThreadPool pool;
const char* test_c = "hello_world";
pool.execute([&]() { print(&test_c, nullptr); });
}
The output of this is:
hello_world
Stopping 0
After that, the main thread halts, because it's waiting for the first thread to join (in the destructor of the ThreadPool). For some reason, the m_running variable of the workers is not set to false, which keeps the application running indefinitely.
In Worker::stop the member m_running is written in the main thread, while it is read in execute in a different thread. This is undefined behavior. You need to protect read/write access from different threads. In this case I would recommend using std::atomic<bool> for m_running.
Edit: the same holds for m_hasData.
Now all 5 threads are running. However after 5 threads are run for the first time. Only first thread (thread # 0) runs infinitely blocking rest of the threads. I only see thread # 0 idle (waiting) and consuming (eating) and again entering into infinite loop other 4 threads do not get a chance after 1st round.
struct sem_t_ * sem[5];
struct sem_t_ * lock;
class Phil
{
public:
Phil()
{
isThinking = isEating = 0;
mId = 0;
}
//~Phil();
bool isThinking;
bool isEating;
int mId;
void setID(int id)
{
mId = id;
}
void think()
{
isThinking = 1;
isEating = 0;
cout<<"Thread "<<mId<<" is idle!.\n";
}
void eat()
{
isThinking = 0;
isEating = 1;
cout<<"Thread "<<mId<<" is consuming!.\n";
}
};
void pause()
{
Sleep(1000);
}
Phil* pArray = new Phil[5];
void* thread_Create(void*param)
{
int value = 0;
int* id = (int*)param;
for(;;)
{
cout<<"Thread Id = "<<*id<<" running.\n";
pArray[*id].think();
sem_wait(&lock);
int left = *id;
int right = (*id)+1;
if( right > 4) right = 0;
//cout<<"Left = "<<left<<" Right = "<<right<<endl;
sem_getvalue(&sem[left],&value) ;
//cout<<"Left Value = "<<value<<endl;
if( value != 1 )
{
sem_post(&lock);
continue;
}
if( value != 1 )
{
sem_post(&lock);
continue;
}
sem_wait(&sem[left]);
sem_wait(&sem[right]);
pArray[*id].eat();
sem_post(&sem[left]);
sem_post(&sem[right]);
sem_post(&lock);
pause();
}
return 0;
}
void main(void)
{
int i = 0;
for(i=0; i< 5;i++)
{
pArray[i].setID(i);
sem_init(&sem[i],0,1);
}
sem_init(&lock, 0, 5);
pthread_t threads[5];
for(i=0; i< 5;i++)
{
pthread_create(&threads[i],NULL,thread_Create, (void*)&i);
pause();
}
for(i=0; i< 5;i++)
{
pthread_join(threads[i], NULL); //Main thread will block until child threads exit!
}
for(i=0; i< 5;i++)
{
sem_destroy(&sem[i]);
}
sem_destroy(&lock);
}
Your problem is in this line:
pthread_join(threads[i], NULL); //Main thread will block until child threads exit!
It is doing exactly what your comment says - your main thread creates one thread (thread 0) and then blocks until thread 0 finishes, which it never does. So your main program never creates any more threads.
The solution is to move the pthread_join calls into another loop. i.e. create all the threads first, then wait for them all to finish.