I am trying to make a server(multithreading) and I run into a problem: it is filling up memory. So I decided to do a simple test. Here is the code in main:
int main(void)
{
int x;
while(1)
{
cin>>x;
uintptr_t thread = 0;
//handle(NULL);
thread = _beginthread(handle, 0, NULL);
if (thread == -1) {
fprintf(stderr, "Couldn't create thread: %d\n", GetLastError());
}
}
}
And here is the 'handle' function:
void handle(void *)
{
;
}
I open task manager, and I am looking there to see how much RAM my process takes.
If the function main is as you see right now, after each press of key 1 and then press enter(so the thing inside the while will execute), the RAM that the process takes increases with 4k(basically, each time the thread is created or something like that, it will leak 4k of memory). If I do this multiple times, it will keep increasing, each time with 4k.
If in the function main I comment this 'thread = _beginthread(handle, 0, 0);' and uncomment this '//handle(NULL);', then the process will not increase it's RAM memory.
Anyone have any ideas how to free that 4k of memory?
I am compiling it with codeblocks, but same result is compiling it with visual studio.
EDIT: from MSDN: "When the thread returns from that routine, it is terminated automatically."
Also I put '_endthread();' in my handle function, but the result IS THE SAME!
Each time around the loop this program creates a new thread. The program never closes any threads.
I think what you have demonstrated is that the memory cost of creating a thread is around 4K.
Presuming you don't want an ever-increasing number of threads, either you should close one before creating another or at least give up when you've got enough.
On further reflection, the above is wrong. I tried your program, and it will not and cannot do what you say, unless there is some important part of the story you've left out.
The line with "cin" just blocks. I pressed enter a few times, but nothing interesting happened. So I took it out.
This program does not leak. Each thread terminates when the handle function finishes.
Here is the code I wrote, adapting yours.
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;
int nthread = 0;
void handle(void *) {
nthread++;
}
int main(int argc, char* argv[]) {
while(nthread < 50000) {
cout << nthread << ' ';
uintptr_t thread = 0;
thread = _beginthread(handle, 0, NULL);
if (thread == -1) {
fprintf(stderr, "Couldn't create thread: %d\n", GetLastError());
break;
}
}
}
It runs 50,000 iterations and uses a grand total of less than 1MB of memory. Exactly as expected.
Something doesn't add up.
Every thread need some memory for it's own infrastructure, that's what the 4K is. When the thread terminates (this depends on your implementation), this 4K will be freed. You should use API functions for joining the the child threads, therefore you should keep the handle(s). Calling the handle function directly is just a function call, no memory is allocated in this case.
EDIT:
Your "handle" function terminates immediately. As far as I know (at least for posix/linux) there are options at creation time for auto-free the memory, or otherwise joining is required. The one thread you see is the "main" thread of the process itself. This way your programm is producing memory leaks.
Related
I am very new to this topic. Its confusing whenever I try to get one process done after another, The next process kicks in before executing the first process.
For example : I am reading from the shared memory , I want the next write process wait until the read is over. But after reading some portion the write process comes in and changes the values.
I have tried to code using mutex and cond_wait. Maybe there are some errors or I dont know really how cond_wait works properly. Need help
my code snippet:
void create_reader()
{
pthread_mutex_lock(&mutex);
if (0 == fork()) {
reader();
exit(0);
}
readerID++;
r+=1;
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
}
void create_writer()
{
pthread_mutex_lock(&mutex);
while (!r)
{
cout<<"waiting"<<endl;
pthread_cond_wait(&condition,&mutex);
}
if (0 == fork()) {
writer();
exit(0);
}
pthread_mutex_unlock(&mutex);
writerID++;
}
As fork() will create a copy of the running process, if the writer change the memory in the second process, the reader will never see the memory modification in its own:
threads share memory
processes don't (unless you share memory with mmap)
That said, your other pthread functions calls seem correct.
See http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them
I was trying to run a function on multiple pthreads in order to increase efficiency and runtime. This function performs a lot of matrix calculations and print statements. However, when I ran tests in order see the performance improvement, the single threaded code ran faster.
My tests went as follows:
-For the single-threaded: Run a for loop 1:1000 that called the function.
-For the multi-pthreaded: Spawn 100 pthreads, have a queue of 1000 items and a pthread_cond_wait and have the threads run the function until the queue is empty.
Here is my code for the pthreads (single-threaded is just a for loop instead):
# include <iostream>
# include <string>
# include <pthread.h>
# include <queue>
using namespace std;
# define NUM_THREADS 100
int main ( );
queue<int> testQueue;
void *playQueue(void* arg);
void matrix_exponential_test01 ( );
void matrix_exponential_test02 ( );
pthread_mutex_t queueLock;
pthread_cond_t queue_cv;
int main()
{
pthread_t threads[NUM_THREADS];
pthread_mutex_init(&queueLock, NULL);
pthread_cond_init (&queue_cv, NULL);
for( int i=0; i < NUM_THREADS; i++ )
{
pthread_create(&threads[i], NULL, playQueue, (void*)NULL);
}
pthread_mutex_lock (&queueLock);
for(int z=0; z<1000; z++)
{
testQueue.push(1);
pthread_cond_signal(&queue_cv);
}
pthread_mutex_unlock (&queueLock);
pthread_mutex_destroy(&queueLock);
pthread_cond_destroy(&queue_cv);
pthread_cancel(NULL);*/
return 0;
}
void* playQueue(void* arg)
{
bool accept;
while(true)
{
pthread_cond_wait(&queue_cv, &queueLock);
accept = false;
if(!testQueue.empty())
{
testQueue.pop();
accept = true;
}
pthread_mutex_unlock (&queueLock);
if(accept)
{
runtest();
}
}
pthread_exit(NULL);
}
My intuition tells me that the multi-threaded version should run faster, but it doesnt. Is there a reason, or is my code faulty? I am using C++ on Windows, and had to download a library to use pthreads.
First, your code is written in a way that only one thread will run at any time (your mutex is locked the whole time the thread is doing work). So at best you can expect your Code to be as fast as the single threaded version.
Also, all threads reading and writing the same memory each time. This way you force your CPU cores to synchronize their caches, meaning actually more load on the bus than would be caused by a single thread. Since you are not doing any computationally expensive stuff, it is likely that memory bandwidth is your actual bottleneck and thus the bus load added by cache synchronization slows down your program. Take a look at http://en.wikipedia.org/wiki/False_sharing for more information.
If runtest() is CPU-bound -- that is, doesn't do anything which might block on i/o or the like -- then there's not much point starting 100 threads, unless you have 100 cpus/cores ! [Edit: I now notice that runtest() does some print statements... file i/o probably won't block... so won't release the CPU.]
The code as currently shown holds the mutex while filling the queue, so nothing will start until the queue is full. By the time filling of the queue has finished signalling 1000 times, if any have reached the pthread_cond_wait(), then hopefully they will all have been started -- so all 100 will be waiting on the mutex.
As currently shown the waiting in playQueue() is broken. It should be something along the lines of:
pthread_mutex_wait(&queueLock) ;
while (testQueue.empty)
pthread_cond_wait(&queue_cv, &queueLock) ;
if (testQueue.eof)
val = NULL ;
else
val = testQueue.pop ;
pthread_mutex_unlock(&queueLock) ;
But, even when this is all sorted out, there is no guarantee you will see an improvement in performance, unless runtest() does a serious amount of work. [Edit: I now notice that it does "a lot of matrix calculations", which sounds like it could be plenty of work.]
One small suggestion, starting the worker threads and filling the queue could be overlapped, by (for instance) starting one worker with the job of starting all the others, or starting a thread to fill the queue.
Without knowing more about the problem, if the work can be statically divided across the worker threads -- for instance, give the first thread items 0..9, the second thread items 10..19, and so on -- so each worker can ignore all the others, reducing the amount of synchronisation operations.
In addition to the other good answers, you said your runtest() function does I/O.
So you could well be I/O bound, in which case all your threads have to wait in line like everybody else to empty out their buffers.
I'm trying to get a hold on pthreads. I see some people also have unexpected pthread behavior, but none of the questions seemed to be answered.
The following piece of code should create two threads, one which relies on the other. I read that each thread will create variables within their stack (can't be shared between threads) and using a global pointer is a way to have threads share a value. One thread should print it's current iteration, while another thread sleeps for 10 seconds. Ultimately one would expect 10 iterations. Using break points, it seems the script just dies at
while (*pointham != "cheese"){
It could also be I'm not properly utilizing code blocks debug functionality. Any pointers (har har har) would be helpful.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <string>
using namespace std;
string hamburger = "null";
string * pointham = &hamburger;
void *wait(void *)
{
int i {0};
while (*pointham != "cheese"){
sleep (1);
i++;
cout << "Waiting on that cheese " << i;
}
pthread_exit(NULL);
}
void *cheese(void *)
{
cout << "Bout to sleep then get that cheese";
sleep (10);
*pointham = "cheese";
pthread_exit(NULL);
}
int main()
{
pthread_t threads[2];
pthread_create(&threads[0], NULL, cheese, NULL);
pthread_create(&threads[1], NULL, wait, NULL);
return 0;
}
The problem is that you start your threads, then exit the process (thereby killing your threads). You have to wait for your threads to exit, preferably with the pthread_join function.
If you don't want to have to join all your threads, you can call pthread_exit() in the main thread instead of returning from main().
But note the BUGS section from the manpage:
Currently, there are limitations in the kernel implementation logic for
wait(2)ing on a stopped thread group with a dead thread group leader.
This can manifest in problems such as a locked terminal if a stop sig‐
nal is sent to a foreground process whose thread group leader has
already called pthread_exit().
According to this tutorial:
If main() finishes before the threads it has created, and exits with pthread_exit(), the other threads will continue to execute. Otherwise, they will be automatically terminated when main() finishes.
So, you shouldn't end the main function with the statement return 0;. But you should use pthread_exit(NULL); instead.
If this doesn't work with you, you may need to learn about joining threads here.
I am trying to make a small thread example. I want to have a variable and each thread try to increment it and then stop once it gets to a certain point. Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly. This is my first day coding threads so feel free to point out anything unnecessary in the code here -
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define NUM_THREADS 2
pthread_t threads[NUM_THREADS];
pthread_mutex_t mutexsum;
int NUMBER = 0;
void* increaseByHundred(void* threadid) {
if(pthread_mutex_lock(&mutexsum))
cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";
else {
for(int i=0;i<100;i++) {
NUMBER++;
cout<<"\nNUMBER: "<<NUMBER;
}
pthread_mutex_unlock(&mutexsum);
pthread_exit((void*)0);
}
}
int main(int argc, char** argv) {
int rc;
int rc1;
void* status;
pthread_attr_t attr;
pthread_mutex_init(&mutexsum, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
rc = pthread_create(&threads[0], &attr, increaseByHundred, (void*)0);
rc1 = pthread_create(&threads[1], &attr, increaseByHundred, (void*)1);
pthread_attr_destroy(&attr);
while(NUMBER < 400)
pthread_join(threads[0], &status);
pthread_mutex_destroy(&mutexsum);
pthread_exit(NULL);
}
I was following a tutorial found here https://computing.llnl.gov/tutorials...reatingThreads
and tried to adapt their mutex example to this idea. The code increments it up to 199 and then stops. I'm guessing because the threads are only doing their routine once. Is there a way make them just do their routine other than when you create them so I could say
while something
do your routine
?
I have the pthread_join there just because it was similar to what that tutorial had on theirs. I don't really even get it that clearly though. I'm pretty sure that line is the problem...I just don't know how to fix it. Any help is appreciated.
Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly.
Why do you want that? You are just learning about threads. Learn the basics first. Don't go diving off the deep end into pthread_mutex_trylock or mutexes configured for error checking. You need to learn to walk before you can learn how to run.
The basics involves a mutex initialized use with default settings and using pthread_mutex_lock to grab the lock. With the default settings, pthread_mutex_lock will only return non-zero if there are big, big problems. There are only two problems that can occur here: Deadlock, and a bad mutex pointer. There is no recovery from either; the only real solution is to fix the code. About the only thing you can do here is to throw an exception that you don't catch, call exit() or abort(), etc.
That some other thread has locked the mutex is not a big problem. It is not a problem at all. pthread_mutex_lock will block (e.g., go to sleep) until the lock becomes available. A zero return from pthread_mutex_lock means that the calling thread now has the lock. Just make sure you release the lock when you are done working with the protected memory.
Edit
Here's a suggestion that will let you see that the threading mechanism is working as advertised.
Upon entry to increaseByHundred print a time-stamped message indicating entry to the function. You probably want to use C printf here rather than C++ I/O. printf() and related functions are thread-safe. C++ 2003 I/O is not.
After a successful return from pthread_mutex_lock print another time-stamped message indicating that a successful lock.
sleep() for a few seconds and then print yet another time-stamped message prior to calling pthread_mutex_unlock().
Do the same before calling pthread_exit().
One last comment: You are checking for an error return from pthread_mutex_lock. For completeness, and because every good programmer is paranoid as all get out, you should also check the return status from pthread_mutex_unlock.
What about pthread_exit? It doesn't have a return status. You could print some message after calling pthread_exit, but you will only reach that statement if you are using a non-compliant version of the threads library. The function pthread_exit() cannot return to the calling function. Period. Worrying about what happens when pthreads_exit() returns is a tinfoil hat exercise. While good programmers should be paranoid beyond all get out, they should not be paranoid schizophrenic.
pthread_mutex_lock will normally just block until it acquire the lock, and that's why the line cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT"; is not ran.
You also have problems in
while(NUMBER < 400)
pthread_join(threads[0], &status);
because you just have 2 threads and number will never reach 400. You also want to join thread[0] on first iteration, then thread[1]...
pthread_mutex_trylock():
if (pthread_mutex_trylock(&mutex) == EBUSY) {
cout << "OMG NO WAY ITS LOCKED" << endl;
}
It is also worth noting that if the mutex is not locked, it will be able to acquire the lock and then it will behave like a regular pthread_mutex_lock().
Can you tell me how can I use threads in C++ programs, and how can I compile it as it will be multithreaded? Can you tell me some good site where I can start from root?
Thanks
I haven't used it myself, but I'm told that the Boost thread libraries make it incredibly easy.
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
For Unix/Linux/BSD, there's pthread library: tutorial.
I guess there are equivalent in Win32 API.
Process and Threads
Synchronization
I use tbb_thread class from intel threading building blocks library.
There are many threads libraries wich are compatible with c++. So at first you must select one. I prefer OpenMP or POSIX threads (also known as pthreads). How to compile it depends on library you have choose.
I use a library my university prof wrote. It is very simple to implement and works really well (used it for quite some time now). I will ask his permission to share it with you.
Sorry for the wait ahead, but gotta check :)
++++++EDIT+++++++
Ok, so I talked to my prof and he doesn't mind if I share it here. Below are the .h and .cpp files for the 'RT Library' written by Paul Davies
http://www.filefactory.com/file/7efbeb/n/rt_h
http://www.filefactory.com/file/40d9a6/n/rt_cpp
Some points to be made about threads and the use of this library:
0) This tutorial will explain thread creation and use on a windows platform.
1) Threads in c++ are usually coded as part of the same source (unlike processes where each process has its own source file and function main() )
2) When a process is up and running, it can create other threads by making appropriate Kernel calls.
3) Multiple threads run faster than multiple processes since they are a part of the same process which results in less of an overhead for the OS, and reduced memory requirements.
4) What you will be using in your case is the CThread class in the rt library.
5) (Make sure rt.h and rt.cpp are a part of your 'solution' and make sure to include rt.h in your main.cpp)
6) Below is a part of code from your future main thread (in main.cpp, of course) where you will create the thread using the CThread class.
void main()
{
CThread t1(ChildThread1, ACTIVE, NULL) ;
. . .
t1.WaitForThread() ; // if thread already dead, then proceed, otherwise wait
}
The arguments of t1 in order are: Name of the function acting as our thread, the thread status (it can be either ACTIVE or SUSPENDED - depending on what you want), and last, a pointer to an optional data you may want to pass to the thread at creation. After you execute some code, you'll want to call the WaitForThread() function.
7) Below is a part of code from your future main thread (in main.cpp, of course) where you will describe what the child thread does.
UINT _ _stdcall ChildThread1(void *args)
{
. . .
}
The odd looking thing there is Microsoft's thread signature. I'm sure with a bit of research you can figure out how to do this in other OSs. The argument is the optional data that could be passed to the child at creation.
8) You can find the detailed descriptions of the member functions in the rt.cpp file. Here are the summaries:
CThread() - The constructor responsible for creating the thread
Suspend() - Suspends a child thread effectively pausing it.
Resume() - Wakes up a suspended child thread
SetPriority(int value) - Changes the priority of a child thread to the value
specified
Post(int message) - Posts a message to a child thread
TerminateThread() - Terminates or Kills a child thread
WaitForThread() - Pauses the parent thread until a child thread terminates.
If the child thread has already terminated, parent will not pause
9) Below is an example of a sample complete program. A clever thing you can do is create multiple instantiations of a single thread.
#include “..\wherever\it\is\rt.h” //notice the windows notation
int ThreadNum[8] = {0,1,2,3,4,5,6,7} ; // an array of thread numbers
UINT _ _stdcall ChildThread (void *args) // A thread function
{
MyThreadNumber = *(int *)(args);
for ( int i = 0; i < 100; i ++)
printf( "I am the Child thread: My thread number is [%d] \n", MyThreadNumber) ;
return 0 ;
}
int main()
{
CThread *Threads[8] ;
// Create 8 instances of the above thread code and let each thread know which number it is.
for ( int i = 0; i < 8; i ++) {
printf ("Parent Thread: Creating Child Thread %d in Active State\n", i) ;
Threads[i] = new CThread (ChildThread, ACTIVE, &ThreadNum[i]) ;
}
// wait for threads to terminate, then delete thread objects we created above
for( i = 0; i < 8; i ++) {
Threads[i]->WaitForThread() ;
delete Threads[i] ; // delete the object created by ‘new’
}
return 0 ;
}
10) That's it! The rt library includes a bunch of classes that enables you to work with processes and threads and other concurrent programming techniques. Discover the rest ;)
You may want to read my earlier posting on SO.
(In hindsight, that posting is a little one-sided towards pthreads. But I'm a Unix/Linux kind of guy. And that approach seemed best with respect to the original topic.)
Usage of threads in C/C++:
#include <iostream>
using namespace std;
extern "C"
{
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
}
int main()
{
pthread_t thread1, thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";
int iret1, iret2;
iret1 = pthread_create( &thread1, NULL, print_message_function (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
//printf("Thread 1 returns: %d\n",iret1);
//printf("Thread 2 returns: %d\n",iret2);
cout<<"Thread 1 returns: %d\n"<<iret1;
cout<<"Thread 2 returns: %d\n"<<iret2;
exit(0);
}
void *print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
//printf("%s \n", message);
cout<<"%s"<<message;
}