How to Initalize Tread Local Storage in C - multithreading

static __thread vars* ptr=NULL;
void thread_init(vars* new_vars){
if(new_vars){
ptr=new_vars
}
printf("%p",ptr);
}
__thread is GCC's extention
thread1 is one thread of main
thread1_child is child of thread1
call thread_init(a) in main //ptr is a, not NULL
call thread_init(b) in thread1 //ptr is b, not NULL
call thread_init(NULL) in thread1_child //ptr is NULL,not b
how to dynamically initialize
(ptr of thread1 == ptr of thread1_child) ?

Related

Is it thread safe when 2 threads modifies different member of a class object concurrently?

If thread1 and thread2 execute concurrently without locks, will class A be thread safe.
class A{
private:
Data data_;
next ptr_;
};
A a = new A();
thread1:
A obj1 = a;
obj1.data_ = 5;
thread2:
A obj2 = a;
obj2.ptr_ = another;
It depends. As you mentioned, when the object is queue node, by enqueuing and dequeuing, two threads won't conflict, if they access the node member respectively.

Can't pass a local variable from a thread

I made a thread thread1 which creates another thread thread2. When I try to pass the value of fd (fd declared inside thread2) using pthread_exit from thread2 to thread1 I get a garbage value in retval. But when I declare fd as a global variable I get correct value in retval. I got an answer that this is because the thread is finished so it can't pass the value. But in case of functions, a local variable's scope is also limited inside the function and they do return values. So why can't a thread do that?
Here is the code that I tried:
void *thread2(void *message)
{
int fd;
void *retval;
fd=open(message,O_RDWR);
printf("message is - %s",(char *)message);
pthread_exit(&fd);
}
void *thread1(void *message)
{
void *retval;
pthread_t *tid2;
tido=malloc(sizeof(pthread_t));
pthread_create(tid2,NULL,thread2,message);
pthread_join(*tid2,&retval);
printf("fd in write is-%d\n",*(int *)retval);
pthread_exit(&retval);
}
Um... your int fd is an automatic variable (which we may assume is on the stack), so is out of scope when thread2() returns, so passing a pointer to fd out of the function is probably going to lead to disappointment.
A function can return the value of an automatic (aka local) variable. What it cannot do is return the address of one (not and work, anyway).
What you could do is construct a struct to pass into thread2(), to carry parameters in and results back.

C++11 When To Use A Memory Fence?

I'm writing some threaded C++11 code, and I'm not totally sure on when I need to use a memory fence or something. So here is basically what I'm doing:
class Worker
{
std::string arg1;
int arg2;
int arg3;
std::thread thread;
public:
Worker( std::string arg1, int arg2, int arg3 )
{
this->arg1 = arg1;
this->arg2 = arg2;
this->arg3 = arg3;
}
void DoWork()
{
this->thread = std::thread( &Worker::Work, this );
}
private:
Work()
{
// Do stuff with args
}
}
int main()
{
Worker worker( "some data", 1, 2 );
worker.DoWork();
// Wait for it to finish
return 0;
}
I was wondering, what steps do I need to take to make sure that the args are safe to access in the Work() function which runs on another thread. Is it enough that it's written in the constructor, and then the thread is created in a separate function? Or do I need a memory fence, and how do I make a memory fence to make sure all 3 args are written by the main thread, and then read by the Worker thread?
Thanks for any help!
The C++11 standard section 30.3.1.2 thread constructors [thread.thread.constr] p5 describes the constructor template <class F, class... Args> explicit thread(F&& f, Args&&... args):
Synchronization: the completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.
So everything in the current thread happens before the thread function is called. You don't need to do anything special to ensure that the assignments to the Worker members are complete and will be visible to the new thread.
In general, you should never have to use a memory fence when writing multithreaded C++11: synchronization is built into mutexes/atomics and they handle any necessary fences for you. (Caveat: you are on your own if you use relaxed atomics.)

problem with posix threads c++

If i have 2 threads Thread1 and Thread2, but Thread2 will use some data that are procesed when Thread1 finishes.Is there a way for Thread2 to wait for Thread1 to finish and then get the data ?
If you need the data from thread1 and not just simple locking to prevent concurrent access, then you should use a semaphore:
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
int sem_destroy(sem_t *sem);
The main program runs sem_init before launching the threads. Thread 1 runs a sem_post to indicate it's done. Thread 2 uses a sem_wait to ensure Thread 1 is finished before it starts.
One way is to use condition vars:
Ex:
pthread_mutex_t mx;
pthead_cond_t cond;
void first_f(void *) {
...
pthread_mutex_lock(&mx)
// do something in first function
// the second function is waiting
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mx);
}
return NULL;
}
void second_f(void *) {
...
pthread_mutex_lock(&mx)
pthread_cond_wait(&cond, &mx);
// waiting for first function until we catch a signal
pthread_mutex_unlock(&mx);
}
return NULL;
}
The second way is to use two semaphores. First sem sets to 1, second set to zero. When the first function finishes, it sets first sem to 0, and second sem to 1. The second function waits until second semaphore is setted to 1 by first function and works.
It is called a mutex. pthreads calls the pthread_mutex, you should find them in the docs.
Yes, you can use a mutex to 'guard' the data in question:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

pthread_cond_broadcast problem

Using pthreads in linux 2.6.30 I am trying to send a single signal which will cause multiple threads to begin execution. The broadcast seems to only be received by one thread. I have tried both pthread_cond_signal and pthread cond_broadcast and both seem to have the same behavior. For the mutex in pthread_cond_wait, I have tried both common mutexes and separate (local) mutexes with no apparent difference.
worker_thread(void *p)
{
// setup stuff here
printf("Thread %d ready for action \n", p->thread_no);
pthread_cond_wait(p->cond_var, p->mutex);
printf("Thread %d off to work \n", p->thread_no);
// work stuff
}
dispatch_thread(void *p)
{
// setup stuff
printf("Wakeup, everyone ");
pthread_cond_broadcast(p->cond_var);
printf("everyone should be working \n");
// more stuff
}
main()
{
pthread_cond_init(cond_var);
for (i=0; i!=num_cores; i++) {
pthread_create(worker_thread...);
}
pthread_create(dispatch_thread...);
}
Output:
Thread 0 ready for action
Thread 1 ready for action
Thread 2 ready for action
Thread 3 ready for action
Wakeup, everyone
everyone should be working
Thread 0 off to work
What's a good way to send signals to all the threads?
First off, you should have the mutex locked at the point where you call pthread_cond_wait(). It's generally a good idea to hold the mutex when you call pthread_cond_broadcast(), as well.
Second off, you should loop calling pthread_cond_wait() while the wait condition is true. Spurious wakeups can happen, and you must be able to handle them.
Finally, your actual problem: you are signaling all threads, but some of them aren't waiting yet when the signal is sent. Your main thread and dispatch thread are racing your worker threads: if the main thread can launch the dispatch thread, and the dispatch thread can grab the mutex and broadcast on it before the worker threads can, then those worker threads will never wake up.
You need a synchronization point prior to signaling where you wait to signal till all threads are known to be waiting for the signal. That, or you can keep signaling till you know all threads have been woken up.
In this case, you could use the mutex to protect a count of sleeping threads. Each thread grabs the mutex and increments the count. If the count matches the count of worker threads, then it's the last thread to increment the count and so signals on another condition variable sharing the same mutex to the sleeping dispatch thread that all threads are ready. The thread then waits on the original condition, which causes it release the mutex.
If the dispatch thread wasn't sleeping yet when the last worker thread signals on that condition, it will find that the count already matches the desired count and not bother waiting, but immediately broadcast on the shared condition to wake workers, who are now guaranteed to all be sleeping.
Anyway, here's some working source code that fleshes out your sample code and includes my solution:
#include <stdio.h>
#include <pthread.h>
#include <err.h>
static const int num_cores = 8;
struct sync {
pthread_mutex_t *mutex;
pthread_cond_t *cond_var;
int thread_no;
};
static int sleeping_count = 0;
static pthread_cond_t all_sleeping_cond = PTHREAD_COND_INITIALIZER;
void *
worker_thread(void *p_)
{
struct sync *p = p_;
// setup stuff here
pthread_mutex_lock(p->mutex);
printf("Thread %d ready for action \n", p->thread_no);
sleeping_count += 1;
if (sleeping_count >= num_cores) {
/* Last worker to go to sleep. */
pthread_cond_signal(&all_sleeping_cond);
}
int err = pthread_cond_wait(p->cond_var, p->mutex);
if (err) warnc(err, "pthread_cond_wait");
printf("Thread %d off to work \n", p->thread_no);
pthread_mutex_unlock(p->mutex);
// work stuff
return NULL;
}
void *
dispatch_thread(void *p_)
{
struct sync *p = p_;
// setup stuff
pthread_mutex_lock(p->mutex);
while (sleeping_count < num_cores) {
pthread_cond_wait(&all_sleeping_cond, p->mutex);
}
printf("Wakeup, everyone ");
int err = pthread_cond_broadcast(p->cond_var);
if (err) warnc(err, "pthread_cond_broadcast");
printf("everyone should be working \n");
pthread_mutex_unlock(p->mutex);
// more stuff
return NULL;
}
int
main(void)
{
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
pthread_t worker[num_cores];
struct sync info[num_cores];
for (int i = 0; i < num_cores; i++) {
struct sync *p = &info[i];
p->mutex = &mutex;
p->cond_var = &cond_var;
p->thread_no = i;
pthread_create(&worker[i], NULL, worker_thread, p);
}
pthread_t dispatcher;
struct sync p = {&mutex, &cond_var, num_cores};
pthread_create(&dispatcher, NULL, dispatch_thread, &p);
pthread_exit(NULL);
/* not reached */
return 0;
}

Resources