I met some confusions when writing a C program.
My scenario has 2 thread but they run serial, so at one time there's single thread. I want to save a parameter in my first thread and I want to get it in my second thread. (pthread here)
So is there anyway to realize this? Public static parameter will be recycled when the thread ends because it belongs to the current thread. I want to save a value or pointer in current process instead of thread so that I can attach it in my next thread...
Is there any possible way to realize this?
Thanks so much!
Threads share the memory. Use a variable (either global, local to the creating thread, or at the heap) and pass a pointer to both threads that points to that very variable.
Related
I'm writing code to save text to a binary file, which includes a function to auto-save text to the binary file, as well as a function to print from the binary file, and I need to incorporate pthread locks and join. We were given
pthread_mutext_t mutex;
pthread_t autosavethread;
as global variables, although the instructor didn't talk about what pthread or mutex actually do, so I'm confused about that.
Also, I understand that I need to use locks whenever shared variables are changed or read (in my case it would be the binary file). But at the end of the file I am supposed to use pthread_join, and I don't know what it does or what arguments are supposed to be used in it. I'm guessing mutex and autosavethread are supposed to be closed, or something along the lines of that, but I don't know how to write it. Can anyone help better my understanding?
There are two types of pthread - joinable thread & detached thread.
If you want to let a thread just take a task and go away once the task is done, you need the detached thread;
If you want to have the communication with the created thread when that thread is done with the assigned job, you have to use joinable thread. Basically it's needed when the parent & its created thread need to communicate after the thread is done.
It's very to google what exactly you need to call the pthread APIs and what can be communicated.
But one thing i want to mention here is, for the joinable thread, you have to explicitly call the pthread_join against the created thread. Otherwise, there will be serious memory leaks. When the joinable thread completes its task, the thread seems to exit (On linux, you can check the /proc/PID/task/ folder and once the thread completes, the entry under it will go away), but the resource allocated for this joinable thread, i.e. stack, is still there in the process memory space. As more and more joinable threads created and completing their tasks, the stacks for each thread are just left in process space, unless you explicitly call the pthread_join. Hope that helps, even a bit
The first argument of pthread_create() is a thread object which is used to identify the newly-created thread. However, I'm not sure I completely understand the implacations of this.
For instance, I am writing a simple chat server and I plan on using threads. Threads will be coming and going at all times, so keeping track of thread objects could be complicated. However, I don't think I should need to identify individual threads. Could I simply use the same thread object for the first argument of pthread_create() over and over again, or are there other ramifications for this?
If you throw away the thread identifiers by overwriting the same variable with the ID of each thread you create, you'll not be able to use pthread_join() to collect the exit status of threads. So, you may as well make the threads detached (non-joinable) when you call pthread_create().
If you don't make the threads detached, exiting threads will continue to use some resource, so continually creating attached (non-detached) threads that exit will use up system resources — a memory leak.
Read the manual at http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html
According to it:
"Upon successful completion, pthread_create() shall store the ID of the created thread in the location referenced by thread."
I think pthread_create just overwrites the value in the first argument. It does not read it, doesn't care what is inside it. So you can get a new thread from pthread_create, but you can't make it reuse an existing thread. If you would like to reuse your threads, that is more complicated.
I need to know how a thread can send its ID to another thread before it goes to wait state. I thought to pass a variable with its ID but I don't know how to do it.
If it's only one thread and its parent, you could use a global variable, as they are shared between all threads. Make it volatile in case you expect concurrent access.
EDIT: I'm not sure if you're using POSIX threads on Linux but you probably have a way to pass a pointer (e.g. to a struct) when creating the thread. It could contain a variable to store its ID or a pointer to a function to call on the parent thread. I know you can do it with Windows threads.
You can create a pointer in the thread which is pointing to the function in the parent (by reference). By the time it goes to wait state then it can just use that pointer to trigger something to its parent.
Threads share memory, so you can allocate a global variable and let the child write on it.
Than for the synchronization (aka inform the parent that a value has been written) you have many choices: you can use a semaphore, can send a signal from the thread back to its parent, use a synchronization variable like explained here.
Is there any way to force threads to have independent address spaces? I'd like to have many threads running loops using local variables - but it seems they all share the same variables.
for example
for (i = args->start; i < args->end; i++) {
printf("%d\n", i);
if (quickFind(getReverse(array[i]), 0, size - 1)) {
printf("%s\n", array[i]);
//strcpy(array[i], "");
}
}
i seems to be shared across threads.
Threads share the memory space of their parent process. Its their characteristic. If you don't want that to happen you can create a new process, which'll have it's own address space, using fork().
If you do decide to use fork() remember that, on successfully creating a child process, it returns 0 to the child process and the PID of the child process to the parent process.
Short answer: Yes it's possible for each thread to have its own copy of the variable i.
Long answer:
All threads share the same address space and the OS does not provide any protection to prevent one thread from accessing memory used by another. However, the memory can be partitioned so that it will only be accessed by a single thread rather than being shared by all threads.
By default each thread receives its own stack. So if you allocate a variable on the stack then it will typically only be accessed by a single thread. Note that it is possible to pass a pointer to a stack variable from one thread to another, but this is not recommended and could be the source of the sort of problems that you are seeing.
Another way for a thread to receive its own copy of a variable is using thread local storage. This allows each thread to have its own copy of a global variable.
In summary, although threads share an address space they can work on private data. But you need to be careful with how you are sharing data between threads and avoid data races.
Just have each thread call into the function separately. Each invocation of a function gets its own instances of all local variables. If this wasn't true, recursion wouldn't work.
If you want to be really lazy, and make no design changes whatsoever (not really recommended), you can modify the declaration of i to something like __thread int i, so that every thread will have its own instance of that variable.
If you were using OpenMP instead of Posix threads, you could also say #pragma omp threadprivate(i) before the first usage of i.
I have threads in my application that wait on condition variable. When the codition is good thread starts to work and reads some data. My data is global variable. Is it possible pass data on runtime without using global data? I read something about specific data but i don't know if it is useful in this case. Thank you!
Yes, you can pass this to your thread routine: pthread_create(thread, attr, function, *USER_ARG*). Simply create a struct for the data you need for the thread to execute.
Where *USER_ARG* is stored in memory is important, you will often want to use the free store (malloc it) for the argument, otherwise you may corrupt the stack of the thread which called pthread_create.