i have a problem with the pthread library in a C-Application for Linux.
In my Application a Thread is started over and over again.
But I allways wait until the Thread is finished before starting it.
At some point the thread doesn't start anymore and I get an out of memory error.
The solution I found is to do a pthread_join after the thread has finished.
Can anyone tell me why the Thread doesn't end correctly?
Here is an Example Code, that causes the same Problem.
If the pthread_join isn't called the Process stops at about 380 calls of the Thread:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
volatile uint8_t check_p1 = 0;
uint32_t stack_start;
void *thread1(void *ch)
{
static int counter = 0;
int i;
int s[100000];
char stack_end;
srand(time(NULL) + counter);
for (i = 0; i < (sizeof (s)/sizeof(int)); i++) //do something
{
s[i] = rand();
}
counter++;
printf("Thread %i finished. Stacksize: %u\n", counter, ((uint32_t) (stack_start)-(uint32_t) (&stack_end)));
check_p1 = 1; // Mark Thread as finished
return 0;
}
int main(int argc, char *argv[])
{
pthread_t p1;
int counter = 0;
stack_start = (uint32_t)&counter; // save the Address of counter
while (1)
{
counter++;
check_p1 = 0;
printf("Start Thread %i\n", counter);
pthread_create(&p1, NULL, thread1, 0);
while (!check_p1) // wait until thread has finished
{
usleep(100);
}
usleep(1000); // wait a little bit to be really sure that the thread is finished
//pthread_join(p1,0); // crash without pthread_join
}
return 0;
}
The solution I found is to do a pthread_join after the thread has finished.
That is the correct solution. You must do that, or you leak thread resources.
Can anyone tell me why the Thread doesn't end correctly?
It does end correctly, but you must join it in order for the thread library to know: "yes, he is really done with this thread; no need to hold resources any longer".
This is exactly the same reason you must use wait (or waitpid, etc.) in this loop:
while (1) {
int status;
pid_t p = fork();
if (p == 0) exit(0); // child
// parent
wait(&status); // without this wait, you will run out of OS resources.
}
Related
I am trying to see the race condition happens in the comsumer-producser problem,
so I made multiple producers and mulitple consumers.
From what I know that I need to provide mutex with semaphore:
Mutex for the race conditions, because muliple producers can access the buffer at the same time. then the data might be corrupted.
And semaphore to provide signaling between the producers and the consumers
The problem here that the sync is happening correctly while I am not using the Mutex (i am using the Semaphore only). is my understanding correct or is there anything wrong to do in the code below:
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
int buffer;
int loops = 0;
sem_t empty;
sem_t full;
sem_t mutex; //Adding MUTEX
void put(int value) {
buffer = value;
}
int get() {
int b = buffer;
return b;
}
void *producer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
sem_wait(&empty);
//sem_wait(&mutex);
put(i);
//printf("Data Set from %s, Data=%d\n", (char*) arg, i);
//sem_post(&mutex);
sem_post(&full);
}
}
void *consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
sem_wait(&full);
//sem_wait(&mutex);
int b = get();
//printf("Data recieved from %s, %d\n", (char*) arg, b);
printf("%d\n", b);
//sem_post(&mutex);
sem_post(&empty);
}
}
int main(int argc, char *argv[])
{
if(argc < 2 ){
printf("Needs 2nd arg for loop count variable.\n");
return 1;
}
loops = atoi(argv[1]);
sem_init(&empty, 0, 1);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
pthread_t pThreads[3];
pthread_t cThreads[3];
pthread_create(&cThreads[0], 0, consumer, (void*)"Consumer1");
pthread_create(&cThreads[1], 0, consumer, (void*)"Consumer2");
pthread_create(&cThreads[2], 0, consumer, (void*)"Consumer3");
//Passing the name of the thread as paramter, Ignore attr
pthread_create(&pThreads[0], 0, producer, (void*)"Producer1");
pthread_create(&pThreads[1], 0, producer, (void*)"Producer2");
pthread_create(&pThreads[2], 0, producer, (void*)"Producer3");
pthread_join(pThreads[0], NULL);
pthread_join(pThreads[1], NULL);
pthread_join(pThreads[2], NULL);
pthread_join(cThreads[0], NULL);
pthread_join(cThreads[1], NULL);
pthread_join(cThreads[2], NULL);
return 0;
}
I believe I have the problem figured out. Here's what is happening
When initializing your semaphores you set empty's number of threads to 1 and full's to 0
sem_init(&empty, 0, 1);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
This means that there is only one "space" for the thread to get into the critical region. In other words, what your program is doing is
produce (empty is now 0, full has 1)
consume (full is now 0, empty has 0)
produce (empty is now 0, full has 1)
...
It's as if you had a token (or, if you like, a mutex), and you pass that token between consumers and producers. That is actually what the consumer-producer problem is all about, only that in most cases we are worried about having several consumers and producers working at the same time (which means you have more than one token). Here, because you have only one token, you basically have what one mutex would do.
Hope it helped :)
we are developing game server using lua.
the server is single threaded, we'll call lua from c++.
every c++ service will create a lua thread from a global lua state which is shared by all service.
the lua script executed by lua thread will call a c api which will make a rpc call to remote server.
then the lua thread is suspened, because it's c function never return.
when the rpc response get back, we'll continue the c code ,which will return to the lua script.
so, we will have multiple lua thread execute parallel on a same global lua state, but they will never run concurrently. and the suspend is not caused but lua yield function, but from the c side.
is it safe to do something like this?
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include "lua/lua.hpp"
static ucontext_t uctx_main, uctx_func1, uctx_func2;
lua_State* gLvm;
int gCallCnt = 0;
static int proc(lua_State *L) {
int iID = atoi(lua_tostring(L, -1));
printf("begin proc, %s\n", lua_tostring(L, -1));
if(iID == 1)
{
swapcontext(&uctx_func1, &uctx_main);
}
else
{
swapcontext(&uctx_func2, &uctx_main);
}
printf("end proc, %s\n", lua_tostring(L, -1));
return 0;
}
static void func1(void)
{
gCallCnt++;
printf("hello, func1\n");
lua_State*thread = lua_newthread (gLvm);
lua_getglobal(thread, "proc");
char szTmp[20];
sprintf(szTmp, "%d", gCallCnt);
lua_pushstring(thread, szTmp);
int iRet = lua_resume(thread, gLvm, 1);
printf("lua_resume return:%d\n", iRet);
}
static void func2(void)
{
gCallCnt++;
printf("hello, func2\n");
lua_State*thread = lua_newthread (gLvm);
lua_getglobal(thread, "proc");
char szTmp[20];
sprintf(szTmp, "%d", gCallCnt);
lua_pushstring(thread, szTmp);
int iRet = lua_resume(thread, gLvm, 1);
printf("lua_resume return:%d\n", iRet);
}
int main(int argc, char *argv[]){
int iRet = 0;
gLvm = luaL_newstate();
luaL_openlibs(gLvm);
lua_pushcfunction(gLvm, proc);
lua_setglobal(gLvm, "proc");
char func1_stack[16384];
char func2_stack[16384];
getcontext(&uctx_func1);
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
getcontext(&uctx_func2);
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
uctx_func2.uc_link = &uctx_main;
makecontext(&uctx_func2, func2, 0);
swapcontext(&uctx_main, &uctx_func1);
swapcontext(&uctx_main, &uctx_func2);
swapcontext(&uctx_main, &uctx_func1);
swapcontext(&uctx_main, &uctx_func2);
printf("hello, main\n");
return 0;
}
In the following code execute_on_thread() will keep on printing ".",
while the main function waits for a condition to be signaled from execute_on_thread using pthread_cond_timedwait. However, it is not timing out after the specified 20 second timeout, it just keeps printing ".", nothing else is happening.
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define SHOW_TECH_CMD_MAX_EXEC_TIME 5 //in secs
pthread_mutex_t waitMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t waitCond = PTHREAD_COND_INITIALIZER;
void *execute_on_thread();
void *execute_on_thread()
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_mutex_lock( &waitMutex );
while(1)
{
printf(".");
}
pthread_cond_signal( &waitCond );
pthread_mutex_unlock( &waitMutex );
return (void *) 0;
}
int main( )
{
pthread_t tid;
struct timespec ts;
int error;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 20;
pthread_create(&tid,NULL,execute_on_thread,NULL);
pthread_mutex_lock(&waitMutex);
error = pthread_cond_timedwait(&waitCond, &waitMutex,&ts);
pthread_mutex_unlock(&waitMutex);
printf("come here 1\n");
if(error == ETIMEDOUT)
{
printf("come here 2\n");
error = pthread_cancel(tid);
if(error != 0)
{
printf("come here 3\n");
}
}
}
Have a look at the documentation for pthread_cond_wait:
Upon successful return, the mutex shall have been locked and shall be
owned by the calling thread.
So, before pthread_cond_wait returns, be it due to a signal arriving or timing out, it tries to lock the mutex. But - since execute_on_thread never releases the mutex once it has it (due to the while(1) loop), pthread_cond_wait will be stuck waiting on the mutex to be unlocked.
If you for instance change your execute_on_thread to temporarily unlock the mutex during each cycle, you should be able to get it to work. For instance:
void *execute_on_thread()
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //Not necessary - this is the default state for new threads
pthread_mutex_lock( &waitMutex );
while(1)
{
printf(".\n");
pthread_mutex_unlock(&waitMutex);
usleep(100*1000); //So that the screen doesn't completely fill up with '.'s
pthread_mutex_lock( &waitMutex );
}
pthread_cond_signal( &waitCond );
pthread_mutex_unlock( &waitMutex );
return (void *) 0;
}
Note though, that there are a couple of other things that could be improved in your program - such as adding a guard variable to your conditional wait (have a look at condition variable - why calling pthread_cond_signal() before calling pthread_cond_wait() is a logical error?), adding a cleanup handler to make sure the mutex is unlocked if the cancel request is handled by execute_on_thread when the mutex is locked and similar tweaks.
Is this the correct way to sync threads without mutex.
This code should be running for a long time
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/memory_order.hpp>
#include <atomic>
std::atomic<long> x =0;
std::atomic<long> y =0;
boost::mutex m1;
// Thread increments
void Thread_Func()
{
for(;;)
{
// boost::mutex::scoped_lock lx(m1);
++x;
++y;
}
}
// Checker Thread
void Thread_Func_X()
{
for(;;)
{
// boost::mutex::scoped_lock lx(m1);
if(y > x)
{
// should never hit until int overflows
std::cout << y << "\\" << x << std::endl;
break;
}
}
}
//Test Application
int main(int argc, char* argv[])
{
boost::thread_group threads;
threads.create_thread(Thread_Func);
threads.create_thread(Thread_Func_X);
threads.join_all();
return 0;
}
Without knowing exactly what you're trying to do, it is hard to say it is the "correct" way. That's valid code, it's a bit janky though.
There is no guarantee that the "Checker" thread will ever see the condition y > x. It's theoretically possible that it will never break. In practice, it will trigger at some point but x might not be LONG_MIN and y LONG_MAX. In other words, it's not guaranteed to trigger just as the overflow happens.
I am working on Ubuntu 12.04.2 LTS. I have a strange problem with pthread_kill(). The following program ends after writing only "Create thread 0!" to standard output. The program ends with exit status 138.
If I uncomment "usleep(1000);" everything executes properly. Why would this happen?
#include <nslib.h>
void *testthread(void *arg);
int main() {
pthread_t tid[10];
int i;
for(i = 0; i < 10; ++i) {
printf("Create thread %d!\n", i);
Pthread_create(&tid[i], testthread, NULL);
//usleep(1000);
Pthread_kill(tid[i], SIGUSR1);
printf("Joining thread %d!\n", i);
Pthread_join(tid[i]);
printf("Joined %d!", i);
}
return 0;
}
void sighandlertest(int sig) {
printf("print\n");
pthread_exit();
//return NULL;
}
void* testthread(void *arg) {
struct sigaction saction;
memset(&saction, 0, sizeof(struct sigaction));
saction.sa_handler = &sighandlertest;
if(sigaction(SIGUSR1, &saction, NULL) != 0 ) {
fprintf(stderr, "Sigaction failed!\n");
}
printf("Starting while...\n");
while(true) {
}
return 0;
}
If the main thread does not sleep a bit before raising the SIGUSR1, the signal handler for the thread created most propably had not been set up, so the default action for receiving the signal applies, which is ending the process.
Using sleep()s to synchronise threads is not recommended as not guaranteed to be reliable. Use other mechanics here. A condition/mutex pair would be suitable.
Declare a global state variable int signalhandlersetup = 0, protect access to it by a mutex, create the thread, make the main thread wait using pthread_cond_wait(), let the created thread set up the signal handle for SIGUSR1, set signalhandlersetup = 0 and then signal the condition the main thread is waiting on using pthread_signal_cond(). Finally let the main thread call pthread_kill() as by your posting.