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.
Related
I'm completely new to multithreading and have a little trouble understanding how multithreading actually works.
Let's consider the following example of code. The program simply takes file names as input and counts the number of lowercase letters in them.
#include <iostream>
#include <thread>
#include <mutex>
#include <memory>
#include <vector>
#include <string>
#include <fstream>
#include <ctype.h>
class LowercaseCounter{
public:
LowercaseCounter() :
total_count(0)
{}
void count_lowercase_letters(const std::string& filename)
{
int count = 0;
std::ifstream fin(filename);
char a;
while (fin >> a)
{
if (islower(a))
{
std::lock_guard<std::mutex> guard(m);
++total_count;
}
}
}
void print_num() const
{
std::lock_guard<std::mutex> guard(m);
std::cout << total_count << std::endl;
}
private:
int total_count;
mutable std::mutex m;
};
int main(){
std::vector<std::unique_ptr<std::thread>> threads;
LowercaseCounter counter;
std::string line;
while (std::cin >> line)
{
if (line == "exit")
break;
else if (line == "print")
counter.print_num(); //I think that this should print 0 every time it's called.
else
threads.emplace_back(new std::thread(&LowercaseCounter::count_lowercase_letters, counter, line));
}
for (auto& thread : threads)
thread->join();
}
Firstly I though that the output of counter.print_num() will print 0 as far as the threads are not 'joined' yet to execute the functions. However, It turns out that the program works correctly and the output of counter.print_num() is not 0. So I asked myself the following questions.
What actually happens when a thread is constructed?
If the program above works fine, then thread must be executed when is created, then what does std::thread::join method do?
If the thread is executed at the time of creation, then what's the point of using multithreading in this example?
Thanks in advance.
You seem to be under the impression that the program can only be running one thread at a time, and that it needs to interrupt whatever it's doing in order to execute the code of the thread. That's not the case.
You can think of a thread as a completely separate program that happens to share memory and resources with the program that created it. The function you pass as an argument is that program's 'main()` for every intent and purpose. In Linux, threads are literally separate processes, but as far as C++ is concerned, that's just an implementation detail.
So, in a modern operating system with preemptive multitasking, much like multiple programs can run at the same time, threads can also run at the same time. Note that I say can, it's up to the compiler and OS to decide when to give CPU time to each thread.
then what does std::thread::join method do?
It just waits until the thread is done.
So what would happen if I didn't call join() method for each one of threads
It would crash upon reaching the end of main() because attempting to exit the program without joining a non-detached thread is considered an error.
As you said, in c++ the thread is executed when it is created all std::thread::join does is wait for the thread to finish execution.
In your code all the threads will start executing simultaneously in the loop and then the main thread will wait for each thread to finish execution in the next loop.
I have a void function that has a while (true) loop inside of it, and both Sleep(); and std::this_thread::sleep_for(std::chrono::milliseconds()); do nothing. And yes, I am aware I'm sleeping by millisecond and not seconds, by multi-threading I mean I have done:
std::thread nThread(Void);
nThread.detach();
When I just call the method, this issue doesn't occur, and it sleeps just fine.
Essentially what I'm doing:
#include <stdio.h>
#include <thread>
void thisisVoid()
{
while (true)
{
printf("Print");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
std::thread nThread(thisisVoid);
nThread.detach();
}
It's not the sleep that's the problem. You haven't really asked a question, but I think what you're saying is that if you don't detach, you get a crash.
Here's why...
C++ doesn't like you to exit the program with dangling threads. You can either detach them or join them. There's a startup time with your new thread, and if you just exit main at the bottom, your first thread probably hasn't run yet. And it hasn't been allowed to clean up because you haven't joined against it or detached it.
So you have to do one or the other in main(). If you join against it you'll wait until it's done. If you detach it, you could exit before he's even executed.
I have an issue: I create a thread to execute a command line and sometimes it takes a lot of time for waiting. So, I want to kill this thread and I implement below code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
using namespace std;
void* doSomeThing(void *)
{
cout<<"Begin execute"<<endl;
system("svn info http://wrong_link_it's_take_a_lot_of_time_to_execute");
return NULL;
}
int main() {
pthread_t myThread;
int err = pthread_create(&myThread,NULL, &doSomeThing,NULL);
if(err != 0)
{
cout<<"Create thread not success"<<endl;
}
sleep(2);
if(pthread_cancel(myThread) == 0)
{
cout<<"Thread was be kill"<<endl;
}
sleep(3);
cout<<"End of program";
return 0;
}
I'm using pthread_cancel to kill this thread and the line cout<<"Thread was be kill"<<endl; always appear after I execute. It is meant this thread being killed, but I saw the surprise result when I ran it on Eclipse (both on Ubuntu and Windows 7)
Anybody can explain to me why this thread still alive after kill and can you give me some method to resolve this issue.
Thank you.
cancelling a thread is not actually killing it. it just requests cancellation:
pthread_cancel - send a cancellation request to a thread
(from man pthread_cancel).
The pthread_cancel() function sends a cancellation request to the
thread thread. Whether and when the target thread reacts to the
cancellation
request depends on two attributes that are under the control of that thread: its cancelability state and type.
As pointed out by Marcus Müller in his answer, pthread_cancel() not necessarily ends the thread addressed.
Do not use system() if you want to kill what had been run.
Create your own new child process using fork()/exec*().
If it's time to end the child let the parent issue a kill() on the PID returned by fork()ing in 1.
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.
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().