I cannot understand why the following pseudo code is causing a segfault.
Using pthreads to run a function I run into a SEGFAULT initializing an integer to zero.
When my_threaded_function not in threaded context or if I called function from the main thread there is no issue.
The SEGFAULT doesn't occur on initializing rc=0;bu only inside the maze_init function.
I have confirmed that I am out of stack space. But I can't think of what is causing the function to behave differently inside the pthread (no shared memory involved), the address &aa cannot be accessed according to gdb.
Why would a stack variable's address not be on the stack?
int maze_init(Maze*m, char* filename)
{
FILE *fp;
int aa, bb, rc;
aa = 0; /// SEGFAULT HERE
...
return 1;
}
void* my_threaded_function(void* arg)
{
Maze maze;
int rc;
rc = 0;
rc = maze_init(&maze,"test.txt");
return rc;
pthread_exit((void*)1);
}
int main(int argc,char** argv){
pthread_t t;
pthread_create(&t, NULL, my_threaded_function,(void*)0);
sleep(10);
}
edit (fixed code typo to return rc)
I have confirmed that I am out of stack space. But I can't think of
what is causing the function to behave differently inside the pthread
Well for one by default secondary threads have smaller stacks than the "main" thread. You can set the size with pthread_attr_setstacksize.
TLPI says:
Each thread has its own stack whose size is fixed when the thread is
created. On Linux/x86-32, for all threads other than the main thread,
the default size of the per-thread stack is 2 MB. The main thread has
a much larger space for stack growth
So that is one reason why it would work when called normally and fail when called from a secondary thread.
Related
I am trying to create a thread library and my thread is a struct type. Have to follow a certain interface and in that I need to pass the thread by value. For ex: to join on a thread my code is as follows:
int thread_join(thread_t thread, void **status1)
{
printf("Joining thread\n");
long int thId = thread.id;
printf("Thread id: %ld\n", thId);
gtthread_t * thrd = getThreadFromID(thId);
while(thrd->status != EXIT)
{
}
status1 = &(thrd->ret_value);
return 0;
}
And I an passing a struct of type thread_t to this function. My problem is when I see the thread's ID in the calling function, its displayed properly but when I check it in the thread_join function its displayed as 0. The caller function is as follows:
void* caller(void* arg)
{
thread_t th;
thread_create(&th, some_function, NULL);
thread_join(th, NULL);
while(1);
}
Thread create initializes the ID of the thread to a non-zero value and starts the function associated with it.
My thread structure (and other relevant structure is):
typedef enum
{
RUNNING,
WAITING,
CANCEL,
EXIT
} stat;
//Thread
typedef struct
{
ucontext_t t_ctxt;
long int id;
stat status;
void * ret_value;
int isMain;
} thread_t;
int thread_create(thread_t *thread, void *(*start_routine)(void *), void *arg)
{
thread = (thread_t *)malloc(sizeof(thread_t));
thread->id = ++count;
thread->status = RUNNING;
thread->ret_value = NULL;
thread->isMain = 0;
if(getcontext(&(thread->t_ctxt)) == -1)
handle_error("getcontext");
thread->t_ctxt.uc_stack.ss_sp = malloc(SIGSTKSZ);
thread->t_ctxt.uc_stack.ss_size = SIGSTKSZ;
thread->t_ctxt.uc_link = &sched_ctxt;
makecontext(&thread->t_ctxt, (void (*)(void))wrap_func, 2, (void (*)(void))start_routine, arg);
enqueue(gQ, thread);
printf("Thread id: %ld\n", thread->id);
swapcontext(&(curr_thread->t_ctxt),&sched_ctxt);
return 0;
}
Why does this happen? After all, I am passing by value and this should create a copy of the thread with the same values. Thanks.
EDIT:
Basically I am having a queue of threads and there is a scheduler which round-robins. I can post that code here too but I'm sure that's needless and that code works fine.
EDIT2:
I am making a header file from this code and including that header in another file to test it. All my thread_t variables are static. The caller is a function which includes my header file.
What is this line:
thread = (thread_t *)malloc(sizeof(thread_t));
for?
You pass in to thread_create() an address which referrs to a struct thread_t defined in caller() as auto variable.
Doing as you do, you allocate memory to the pointer passed in to thread_create() initialise it and forget the address on return.
The code never writes to the memory being referenced by the address passed in! Besides this it is a memory leak.
To fix this simply remove the line of code quoted above.
You have no mutex guard on thread id getter. Presumably, there is no guard on setter. What can be happening is that the variable is not visible in the other thread yet. And, without a critical section, it may never become visible.
Each variable which is accessed for both read and write from different threads has to be accessed in a critical section (pthread_mutex_lock / unlock).
Another possibility is that you are setting the thread id inside the running thread and you are accessing the variable even before it is set. If you attempt to join immediately after starting a thread it is possible, that the other thread hasn't been run at all yet and the variable is not set.
side note: do yourself a favor and use calloc:)
In caller function,
thread_create(&th, some_function, NULL);
should be
gtthread_create(&th, some_function, NULL);
I'm running the following program. It simply creates threads that die straight away.
What I have found is that after 93 to 98 (it varies slightly) successful calls, every next call to pthread_create() fails with error 11: Resource temporarily unavailable. I think I'm closing the thread correctly so it should give up on any resources it has but some resources become unavailable.
The first parameter of the program allows me to set the interval between calls to pthread_create() but testing with different values, I've learned that the interval does not matter (well, I'll get the error earlier): the number of successful calls will be the same.
The second parameter of the program allows me to set a sleep interval after a failed call but the length of the interval does not seem to make any difference.
Which ceiling am I hitting here?
EDIT: found the error in doSomething(): change lock to unlock and the program runs fine. The question remains: what resource is depleted with the error uncorrected?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>
#include <errno.h>
pthread_mutex_t doSomethingLock;
void milliSleep(unsigned int milliSeconds)
{
struct timespec ts;
ts.tv_sec = floorf(((float)milliSeconds / 1000));
ts.tv_nsec = ((((float)milliSeconds / 1000) - ts.tv_sec)) * 1000000000;
nanosleep(&ts, NULL);
}
void *doSomething(void *args)
{
pthread_detach(pthread_self());
pthread_mutex_lock(&doSomethingLock);
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t doSomethingThread;
pthread_mutexattr_t attr;
int threadsCreated = 0;
if (argc != 3)
{
fprintf(stderr, "usage: demo <interval between pthread_create() in ms> <time to wait after fail in ms>\n");
exit(1);
}
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&doSomethingLock, &attr);
while (1)
{
pthread_mutex_lock(&doSomethingLock);
if (pthread_create(&doSomethingThread, NULL, doSomething, NULL) != 0)
{
fprintf(stderr, "%d pthread_create(): error %d, %m\n", threadsCreated, errno);
milliSleep(atoi(argv[2]));
}
else threadsCreated++;
milliSleep(atoi(argv[1]));
}
}
If you are on a 32 bit distro, you are probably hitting address space limits. The last I checked, glibc will allocate about 13MB for stack space in every thread created (this is just the size of the mapping, not allocated memory). With 98 threads, you will be pushing past a gigabyte of address space of the 3G available.
You can test this by freezing your process after the error (e.g. sleep(1000000) or whatever) and looking at its address space with pmap.
If that is the problem, then try setting a smaller stack size with pthread_attr_setstack() on the pthread_attr_t you pass to pthread_create. You will have to be the judge of your stack requirements obviously, but often even complicated code can run successfully in only a few kilobytes of stack.
Your program does not "create threads that simply die away". It does not do what you think it does.
First, pthread_mutex_unlock() only unlocks a pthread_mutex_t that has been locked by the same thread. This is how mutexes work: they can only be unlocked by the same thread that locked them. If you want the behaviour of a semaphore semaphore, use a semaphore.
Your example code creates a recursive mutex, which the doSomething() function tries to lock. Because it is held by the original thread, it blocks (waits for the mutex to become free in the pthread_mutex_lock() call). Because the original thread never releases the lock, you just pile up new threads on top of the doSomethingLock mutex.
Recursivity with respect to mutexes just means a thread can lock it more than once; it must unlock it the same number of times for the mutex to be actually released.
If you change the pthread_mutex_lock() in doSomething() to pthread_mutex_unlock(), then you're trying to unlock a mutex not held by that thread. The call fails, and then the threads do die immediately.
Assuming you fix your program, you'll next find that you cannot create more than a hundred or so threads (depending on your system and available RAM).
The reason is well explained by Andy Ross: the fixed size stacks (getrlimit(RLIMIT_STACK, (struct rlimit *)&info) tells you how much, unless you set it via thread attributes) eat up your available address space.
The original stack given to the process is resized automatically, but for all other threads, the stack size is fixed. By default, it is very large; on my system, 8388608 bytes (8 megabytes).
I personally create threads with very small stacks, usually 65536 bytes, which is more than enough unless your functions use local arrays or large structures, or do insanely deep recursion:
#ifndef THREAD_STACK_SIZE
#define THREAD_STACK_SIZE 65536
#endif
pthread_attr_t attrs;
pthread_t thread[N];
int i, result;
/* Create a thread attribute for the desired stack size. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
/* Create any number of threads.
* The attributes are only a guide to pthread_create(),
* they are not "consumed" by the call. */
for (i = 0; i < N; i++) {
result = pthread_create(&thread[i], &attrs, some_func, (void *)i);
if (result) {
/* strerror(result) describes the error */
break;
}
}
/* You should destroy the attributes when you know
* you won't be creating any further threads anymore. */
pthread_attr_destroy(&attrs);
The minimum stack size should be available as PTHREAD_STACK_MIN, and should be a multiple of sysconf(_SC_PAGESIZE). Currently PTHREAD_STACK_MIN == 16384, but I recommend using a larger power of two. (Page sizes are always powers of two on any binary architecture.)
It is only the minimum, and the pthread library is free to use any larger value it sees fit, but in practice the stack size seems to be what you set it to, plus a fixed value depending on the architecture, kernel, and the pthread library version. Using a compile-time constant works well for almost all cases, but if your application is complex enough to have a configuration file, it might be a good idea to let the user override the compile-time constant if they want to, in the config file.
I have a Tcl main program and I want to create a C thread from it.
I then would need to share information between the two threads: C thread's process frequently updated inputs/outputs.
I see two possible solutions to my problem: (1) port Tcl's Thread Shared Variable to C, but I didn't see any information about it in the TCL-C API. (2) Create Tcl-C linked Variables and use it as arguments during the C thread creation.
The latter idea doesn't seem to work. Here is the C code:
#include <tcl.h>
/*
startRoutine
*/
static void startRoutine (ClientData clientData) {
int *Var;
Var= (int *) clientData;
int locA=0;
int j;
int k;
while (1) {
if (locA=!*Var) {
// Modify Tcl-C shared variable
locA=2 * *Var;
*Var=locA;
for (j=0; j<100; j++){}
} else {
for (k=0; k<100; k++){}
}
}
}
static int
createThreadC_Cmd(
ClientData cdata,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
// Contains the ID of the newly created thread
Tcl_ThreadId id;
// Thread argument
ClientData limitData;
// Transfering global var argument to the created thread
limitData=cdata;
// Thread creation
id=0;
Tcl_CreateThread(&id, startRoutine, limitData, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS);
// Wait thread process, before returning to TCL prog
int i;
int aa;
for (i=0 ; i<10000000 ; i++){
aa=i;
}
// Return thread ID to tcl prog to allow mutex use
Tcl_SetObjResult(interp, Tcl_NewIntObj((int) id));
return TCL_OK;
}
int DLLEXPORT
Behavcextension_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
// Create global Var
int *sharedPtr;
int linkedVar=0;
sharedPtr=&linkedVar;
Tcl_LinkVar(interp, "linkedVar", (char *) sharedPtr, TCL_LINK_INT);
Tcl_CreateObjCommand(interp,
"createThreadC", createThreadC_Cmd, sharedPtr, NULL);
return TCL_OK;
}
Here is the Tcl code:
# linkedVar initial value in Tcl, will be overwritten by C Tcl_LinkVar() function
set linkedVar 98
puts "linkedVar: $linkedVar"
# Thread creation
#------------------
load [file join [pwd] libBehavCextension[info sharedlibextension]]
set threadId [createThreadC]
puts "Created thread $threadId, waiting"
# When Tcl_LinkVar() is called, initiate linkedVar at 2
puts "linkedVar: $linkedVar"
# Function inside thread should modify linkedVar into linkedVar*2
set linkedVar 98
after 5000
puts "linkedVar: $linkedVar"
The terminal output is here:
Main thread ID: tid0xb779b6c0
linkedVar: 98
Created thread -1227252928, waiting
linkedVar: 2
linkedVar: 98
The last result should be 2*98=196. LinkVar creation between Tcl and C is Ok (we get 2 after link creation), but passing LinkVar to the Thread is KO.
Any solution or explanations about why it doesn't work/what to do to solve it are welcome!
The problem remains the same as in the other question. You're allocating the storage for the variable on the C side on the C stack in a function that terminates shortly afterwards. It's Undefined Behavior to refer to that variable (which is linkedVar in Behavcextension_Init) after the termination of the function (Behavcextension_Init). What actually happens is that the actual storage is used for some other function call (doing who knows what) and so the value contained is arbitrary, and changing it can lead to “exciting” behavior.
You're looking to have a variable that exists after Behavcextension_Init finishes, so it must not be allocated in the stack of that function. The simplest method is this:
int DLLEXPORT
Behavcextension_Init(Tcl_Interp *interp)
{
int *sharedPtr;
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
sharedPtr = (int *) Tcl_Alloc(sizeof(int)); // Allocate
*sharedPtr = 0; // Initialize
Tcl_LinkVar(interp, "linkedVar", (char *) sharedPtr, TCL_LINK_INT);
Tcl_CreateObjCommand(interp,
"createThreadC", createThreadC_Cmd, sharedPtr, NULL);
return TCL_OK;
}
Caveats
This leaks memory, as there is no matching Tcl_Free for that Tcl_Alloc. For memory allocated once per process, that's not much of a problem. After all, it's only a few bytes and the OS will reclaim it at exit.
This is unsafe when reading the variable from a different thread than the one where it was written; there's simply no guarantee that it will work. It will probably work as it is just an integer, but you're depending on the hardware to be cooperative. The right thing to do is to allocate a structure containing both the variable and a suitable mutex, and protect the accesses to the variable (whether reads or writes) with the mutex. That in turn requires that you do not use Tcl_LinkVar — it knows nothing about mutex-protected memory — but Tcl_LinkVar is just a wrapper round Tcl_TraceVar that provides a callback that does the coupling between Tcl's variable (see Tcl_GetVar and Tcl_SetVar) and the C variable; writing your own that knows how to do mutex-protection handling as well is not hard. (If you're interested, get the source to Tcl_LinkVar and adapt it yourself; it doesn't use any private API calls.)
i'm working on gcc ,
i'm wondering if this is possible:
I have a function (NOTmain but aLocalFn) and I declare a local variable in it. Then I pass this local argument as a thread argument. is it doable? or there is the chance (depending on what is run first) that the aLocalVar will be lost before threadFunction is run and the reference idxPtr will be pointing to senselessness??
int *threadFunction(void *idxPtr){
int rec_idx=(int) *idxPtr;
//work in the thread with this variabel rec_idx
}
int aLocalFn(){
int aLocalVar=returnsRecordIndex();
pthread_create(&thread_id,&attr_detached,threadFunction, &aLocalVar)!=0)
return 0;
}
thank you for your help
This code is incorrect. The function aLocalFn may return before the thread function starts executing. And so by the time the thread function reads the local variable, the scope of that variable may have ended.
What can confuse matters is that this code may very well appear to work, at least some of the time. However, it is incorrect and you should use heap allocated memory instead.
your code has a life-time issue with "aLocalVar"
if you just want to pass an integer, here is a non-portable way to do it.
it does not work on some platforms, but you are not likely to encounter those.
void threadFunction ( void * idxptr ) {
int rec_idx = (int) idxptr;
....
}
int rec_idx = returnsRecordIndex();
pthread_create (&thread1, &attr_detached, (void *) &threadFunction, (void *)rec_idx);
It's doable, but it's not done in the code in your question. You will have to add a signal variable to indicate when the new thread is done using the variable. Then your outer function can return.
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t signal = PTHREAD_COND_INITIALIZER;
int done;
int *threadFunction(void *idxPtr){
int rec_idx=(int) *idxPtr;
pthread_mutex_lock(&lock);
done = 1;
pthread_cond_signal(&signal);
pthread_mutex_unlock(&lock);
//work in the thread with this variabel rec_idx
}
int aLocalFn(){
int aLocalVar=returnsRecordIndex();
done = 0;
pthread_create(&thread_id,&attr_detached,threadFunction, &aLocalVar)!=0)
pthread_mutex_lock(&lock);
while (!done)
pthread_cond_wait(&signal, &lock);
pthread_mutex_unlock(&lock);
return 0;
}
Note that this example code is itself not thread safe (if multiple threads call aLocalFn).
This does complicate the code, and locking is expensive. So in most cases you're probably better off storing the data in the heap and letting the new thread or pthread_join code free it.
#pizza's answer is what I'd do. Another way for you to do it would be to use malloc/free as #David hinted at. I would certainly do this over the wait loop proposed in other answers here.
int *threadFunction(void *idxPtr){
int rec_idx = *(int *)idxPtr;
// free up our int buffer
free(idxPtr);
...
}
int aLocalFn(){
int aLocalVar = returnsRecordIndex();
// allocate some space for our int
int *intBuf = (int *)malloc(sizeof(int));
*intBuf = aLocalVar;
pthread_create(&thread_id,&attr_detached,threadFunction, intBuf)!=0)
return 0;
}
Whenever you are passing variables to a thread function, it is your job to ensure that the variable remains alive and valid till the thread function is done using it.
In your case aLocalFn() continues to execute simultaneously with the new thread and may even finish execution before the thread, that leaves you with an dangling pointer(pointer pointing to data that may not exist) in thread function since the local variable aLocalVar in the function ceases to exist after function returns.
I'm trying to use threads (for the first time!) in a GCC C application which works fine in non-threaded mode. When I run it some threads give results which are all zero instead of the required answers (which I know for checking purposes), but the threads giving zeroes are not the same each time I run it. The ones which give non-zero answers are correct, so the code appears to run ok as such. I wonder if anyone can point out areas where I might have something which is not thread-safe.
My own thoughts are it may be due to how I collect results or maybe memory allocation - I use malloc and free but elsewhere in StackOverflow I see that GCC malloc is considered thread-safe if linked with -lpthread (which I am doing). Nothing uses global/static variables - everything is passed as function arguments.
In order to pass results back to main, my threaded routine uses an array of structures. Each thread writes to a distinct element of this array, so they are not trying to write to the same memory. Maybe I need to use some form of locking when writing results even though they don't go to the same element of the structure array?
I followed the recipe for threaded code here:
https://computing.llnl.gov/tutorials/pthreads/#Abstract
I attach (simplified) code extracts in case this gives any clues (I may have omitted/modified something incorrectly but I am not asking for anyone to spot bugs, just the general methodology).
typedef struct p_struct { /* used for communicating results back to main */
int given[CELLS];
int type;
int status;
/*... etc */
} puzstru;
typedef struct params_struct { /* used for calling generate function using threads */
long seed;
char *text;
puzzle *puzzp;
bool unique;
int required;
} paramstru;
/* ========================================================================================== */
void *myfunc(void *spv) /* calling routine for use by threads */
{
paramstru *sp=(paramstru *)spv;
generate(sp->seed, sp->text, sp->puzzp, sp->unique, sp->required);
pthread_exit((void*) spv);
}
/* ========================================================================================== */
int generate(long seed, char *text, puzstru *puzzp, bool unique, int required)
{
/* working code , also uses malloc and free,
puts results in the element of a structure array pointed to by "puzzp",
which is different for each thread
(see calling routine below : params->puzzp=puz+thr; )
extract as follows: */
puzzp->given[ix]=calcgiven[ix];
puzzp->type=1;
puzzp->status=1;
/* ... etc */
}
/* ========================================================================================== */
int main(int argc, char* argv[])
{
pthread_t thread[NUM_THREADS];
pthread_attr_t threadattr;
int thr,threadretcode;
void *threadstatus;
paramstru params[1];
/* ....... ETC */
/* set up params structure for function calling parameters */
params->text=mytext;
params->unique=TRUE;
params->required=1;
/* Initialize and set thread detached attribute */
pthread_attr_init(&threadattr);
pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_JOINABLE);
for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
params->seed=ran_arr_next(startingseeds);
params->puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)params);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}
/* Free thread attribute and wait for the other threads */
pthread_attr_destroy(&threadattr);
for(thr=0; thr<NUM_THREADS; thr++)
{
threadretcode = pthread_join(thread[thr], &threadstatus);
if (threadretcode)
{
printf("ERROR; return code from pthread_join() is %d\n", threadretcode);
exit(-1);
}
printf("Main: completed join with thread %d having a status of %ld\n",thr,(long)threadstatus);
}
/* non-threaded code, print results etc ............. */
free(startingseeds);
free(puz);
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}
For the benefit of others reading this - all the answers were correct, and the answer to the question in the heading is YES, threads can write safely to different elements of the same array of structures, my problem was in the calling routine - the following is the amended code snippet (now works fine):
paramstru params[NUM_THREADS];
for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
/* set up params structure for function calling parameters */
params[thr].text=mytext;
params[thr].unique=TRUE;
params[thr].required=1;
params[thr].seed=ran_arr_next(startingseeds);
params[thr].puzzp=puz+thr;
threadretcode = pthread_create(&thread[thr], &threadattr, myfunc, (void *)¶ms[thr]);
if (threadretcode)
{
printf("ERROR; return code from pthread_create() is %d\n", threadretcode);
exit(-1);
}
}
To answer your question, it is perfectly fine to write to different elements of the same array from different threads without locking. There will only ever be a data race if two threads write to the same byte without synchronizing (e.g., locking).
As other answers point out, the reason your code as-written breaks is because you pass a pointer to the same params object to each of your threads, an then you modify that object. You probably want to create a new param for each thread.
paramstru params[1];
The code is passing the same structure to all threads. Just the thread initialization loop is overwriting the data that a thread should work on:
for(thr=0; thr<NUM_THREADS; thr++)
{
printf("Main: creating thread %d\n", thr);
params->seed=ran_arr_next(startingseeds); /* OVERWRITE */
params->puzzp=puz+thr; /* OVERWRITE */
The reason the non-threaded code works is because each call to myfunc() terminates before the params structure is changed.
You only created one copy of your parameter structure and are overwriting it and passing the same address to each thread. Dont' you want paramstru params[NUM_THREADS];?