I am trying to create a lock using sem_wait() and I have a printf before and after the sem_wait call. (I do not see this being printed: printf("after sem wait ");) The sem_wait call never returns.
sem_t* sem;
Thank you
int 32_t retVal = -1;
printf("before sem wait ");
retVal = sem_wait(sem);
printf("after sem wait ");
How do I debug this issue?
The argument to sem_wait must to point to an actual sem_t object which you've initialized using sem_init. For example:
sem_t sem;
sem_init(&sem, 1);
printf("before sem wait\n");
sem_wait(&sem);
printf("after sem wait\n");
sem_destroy(&sem);
Of course if you're using this object for actual signalling, you'll also need to arrange to call sem_post() elsewhere to increment the semaphore.
Related
I am running SnS on android(L) BT app and using GKI calls under bluedroid. All GKI calls are called from various threads of BT app and we are protecting it by mutex(bionic). It works fine if BT turns on\off for 700+ iteration but after that suddenly i see that the moment mutex gets unlocked by one thread, its value becomes 2 and it does not get back to its old value. I am intitializing the mutex in default manner and really not sure what is happening. In fact i had put buffer padding around mutex to avoid from any corruption but buffer with pattern is not overwritten at all but only the mutex value changes to 2. all threads waiting for this mutex starves.
Please suggest why it can change its value to 2 and how I can stop it.
Line 3121: 01-01 03:30:30.200 1117 15470 E GKI_LINUX: LOCK TRYING : gki addr 0xa4e18e40 **value 16384** value before=1515870810 and after=1515870810
Line 3123: 01-01 03:30:30.200 1117 15470 E GKI_LINUX: LOCKED : gki addr 0xa4e18e40 value 1013858305 value before=1515870810 and after=1515870810
Line 3139: 01-01 03:30:30.200 1117 15470 E GKI_LINUX: UNLOCKED : gki addr 0xa4e18e40 **value 2** value before=1515870810 and after=1515870810 **//ideally it should have been 16384**
P.S. : newbie to linux
Code :
//This function initializes the mutex.
void GKI_init(void)
{
pthread_mutexattr_t attr;
tGKI_OS *p_os;
memset (&gki_cb, 0, sizeof (gki_cb));
gki_buffer_init();
gki_timers_init();
alarm_service_init();
gki_cb.com.OSTicks = (UINT32) times(0);
pthread_mutexattr_init(&attr);
#ifndef __CYGWIN__
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
#endif
p_os = &gki_cb.os;
pthread_mutex_init(&p_os->GKI_mutex, &attr);
/* pthread_mutex_init(&GKI_sched_mutex, NULL); */
/*Store mutex value in backup */
p_os->origval = p_os->GKI_mutex.value;
ALOGE(" backup mutex value is = %d ",p_os->origval);
#if (GKI_DEBUG == TRUE)
pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
#endif
struct sigevent sigevent;
memset(&sigevent, 0, sizeof(sigevent));
sigevent.sigev_notify = SIGEV_THREAD;
sigevent.sigev_notify_function = (void (*)(union sigval))bt_alarm_cb;
sigevent.sigev_value.sival_ptr = NULL;
if (timer_create(CLOCK_REALTIME, &sigevent, &posix_timer) == -1) {
ALOGE("%s unable to create POSIX timer: %s", __func__, strerror(errno));
timer_created = false;
} else {
timer_created = true;
}
}
void GKI_disable (void)
{
pthread_mutex_lock(&gki_cb.os.GKI_mutex);
}
void GKI_enable (void)
{
pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
//Just after this mutex value is getting changed i.e. GKI_mutex.value =2
}
Everytime GKI_disable/ GKI_enable is called before accessing common resources.
I have created 10 threads and want to execute in a round robin fashion for 3 times. Initially all
threads are waiting. Main threads sends signal to thread 0, on receiving signal thread 0 woke up and
then perform some task and then send signal to thread 1 and this repeats like thread1-> thread2->thread3
....->thread9. then thread 9-> thread 0.
I am trying to implement this
thread i, does some task, then send signal to thread (i+1) and then thread i goes for sleep. thread (i+1) will wake up after t sec (means thread i+1 wakeup time - thread i sleep time = t sec ), thread (i+1) will do some task, send signal to thread (i+2) and go for sleep and this will repeat for few(3) times.
Although I am able to send signal from thread 0-> thread 1 -> .... thread 9 (loop executed only once ), I am not able to send signal thread 9 -> thread 0 and that's why I am not able to repeat this loop for 3 times.
where I am making mistakes ?
Any help will be highly appreciated .
I am using g++ 4.6.3 under linux kernel 2.6.32.
Here is my expected output
Create 5 threads
Thread created=0
Thread created=1
Thread created=2
Thread created=3
Thread created=4
Thread 4 blocked
Thread 3 blocked
Thread 2 blocked
Thread 1 blocked
Thread 0 blocked
Wake up all waiting threads...
Thread 0 unblocked
Thread 1 unblocked
Thread 2 unblocked
Thread 3 unblocked
Thread 4 unblocked
Thread 4 blocked // repeataion of same sequence
Thread 3 blocked
Thread 2 blocked
Thread 1 blocked
Thread 0 blocked
Thread 0 unblocked
Thread 1 unblocked
Thread 2 unblocked
Thread 3 unblocked
Thread 4 unblocked
Wait for threads and cleanup
Main completed
Here is my actual output
Create 5 threads
Thread created=0
Thread created=1
Thread created=2
Thread created=3
Thread created=4
Thread 4 blocked
Thread 3 blocked
Thread 2 blocked
Thread 1 blocked
Thread 0 blocked
Wake up all waiting threads...
Thread 0 unblocked
Thread 1 unblocked
Thread 2 unblocked
Thread 3 unblocked
Thread 4 unblocked
Wait for threads and cleanup
Main completed
Here is my code
#include <pthread.h>
#include <iostream>
#include <stdio.h>
/* For safe condition variable usage, must use a boolean predicate and */
/* a mutex with the condition. */
int conditionMet = 0;
pthread_cond_t cond[5];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#define NTHREADS 5
void *threadfunc(void *parm)
{
int i;
long my_id = (long)parm;
int rc;
// Initially all threads will wait
rc = pthread_mutex_lock(&mutex);
printf("Thread %d blocked\n",my_id);
rc = pthread_cond_wait(&cond[my_id], &mutex);
printf("Thread %d unblocked\n", my_id);
rc = pthread_mutex_unlock(&mutex);
int count=0;
while(count++<3) // This line makes no sense, no repeatation as expected.
{
rc = pthread_mutex_lock(&mutex);
while (!conditionMet) {
printf("Thread %d blocked\n",my_id);
rc = pthread_cond_wait(&cond[my_id], &mutex);
printf("Thread %d unblocked\n", my_id);
}
rc = pthread_mutex_unlock(&mutex);
// sending signal to next thread i+1
rc = pthread_mutex_lock(&mutex);
rc = pthread_cond_signal(&cond[(my_id+1)%NTHREADS]);
rc = pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(int argc, char **argv)
{
int rc=0;
int i;
pthread_t threadid[NTHREADS];
for(rc=0;rc<NTHREADS;rc++)
cond[rc]= PTHREAD_COND_INITIALIZER;
printf("Enter Testcase - %s\n", argv[0]);
printf("Create %d threads\n", NTHREADS);
for(i=0; i<NTHREADS; ++i) {
rc = pthread_create(&threadid[i], NULL, threadfunc, (void *)i);
printf("Thread created=%d\n", i);
}
sleep(5); /* Sleep is not a very robust way to serialize threads */
rc = pthread_mutex_lock(&mutex);
/* The condition has occured. Set the flag and wake up any waiting threads */
conditionMet = 1;
printf("Wake up all waiting threads...\n");
rc = pthread_cond_signal(&cond[0]);
rc = pthread_mutex_unlock(&mutex);
printf("Wait for threads and cleanup\n");
for (i=0; i<NTHREADS; ++i) {
rc = pthread_join(threadid[i], NULL);
}
pthread_cond_destroy(&cond[0]);
pthread_mutex_destroy(&mutex);
printf("Main completed\n");
return 0;
}
After referring to pthread_wait I myself solved my problem.
All the threads runs in a round robin sequence for once, then the program terminate/complete execution as NO threads are WAITING for next turn, all finished .
So to run the same sequence multiple (3) times, wait variable needs to modified correctly so that each thread will wait for next turn until 3 execution.
Here is modified program :
void *threadfunc(void *parm)
{
int i;
long my_id = (long)parm;
int rc;
/*
DELETE THIS PORTION, OTHERWISE NO OUTPUT, AGAIN HANGED BEFORE SINGLE SEQUENCE.
IT WILL NOT ENTER INSIDE LOOP while(count++<3)
// Initially all threads will wait
rc = pthread_mutex_lock(&mutex);
printf("Thread %d blocked\n",my_id);
rc = pthread_cond_wait(&cond[my_id], &mutex);
printf("Thread %d unblocked\n", my_id);
rc = pthread_mutex_unlock(&mutex);
*/
int count=0;
while(count++<3)
{
rc = pthread_mutex_lock(&mutex);
while ( conditionMet != my_id)
{
printf("Thread %d blocked\n",my_id);
rc = pthread_cond_wait(&cond[my_id], &mutex);
printf("Thread %d unblocked\n", my_id);
}
rc = pthread_mutex_unlock(&mutex);
rc = pthread_mutex_lock(&mutex);
conditionMet = (my_id+1)%NTHREADS ; // This is important to wait for next time
rc = pthread_cond_signal(&cond[(my_id+1)%NTHREADS]);
rc = pthread_mutex_unlock(&mutex);
}
return NULL;
}
I have a program that is trying to use create and cancel through an implemented pool.
The creation is as follows:
int threadsNum=10;
while (created<threadsNum){
pthread_t newThread;
pthread_struct *st; //Open the thread that handle the deleting of the sessions timeout.
st = (pthread_struct*)malloc(sizeof(pthread_struct));
st->id = created;
st->t = newThread;
pthread_mutex_lock( &mutex_threadsPool );
readingThreadsPool[created] = st;
pthread_mutex_unlock( &mutex_threadsPool );
if((threadRes1 = pthread_create( &newThread, NULL, pcapReadingThread, (void*)created)))
{
syslog(LOG_CRIT, "Creating Pcap-Reading Thread %d failed.",created);
printf( "Creating Pcap-Reading Thread %d failed.\n",created);
exit(1);
}
syslog(LOG_INFO, "Created Pcap-Reading Thread %d Successfully.",created);
created++;
}
Later I try to cancel them and restart them :
pthread_t t;
pthread_struct* tstr;
int i;
pthread_mutex_unlock( &mutex_threadsPool );
//first go on array and kill all threads
for(i = 0; i<threadsNum ; i++ ){
tstr = readingThreadsPool[i];
if (tstr!=NULL){
t = tstr->t;
if (pthread_cancel(t)!=0){
perror("ERROR : Could not kill thread");
}
else{
printf("Killed Thread %d \n",i);
}
}
}
So far so good, but the only problem is that the output is
Error : Could not kill thread : Illegal Seek
Killed Thread 1
Killed Thread 2
Killed Thread 3
Killed Thread 4
Killed Thread 5
Killed Thread 6
Killed Thread 7
Killed Thread 8
Killed Thread 9
Why doesn't it kill the thread in the 0 index as well?
And I couldn't find anything about Illegal Seek..
Thanks for your help people
Thanks
The problem is that newThread is being used before it is initialized:
pthread_t newThread;
pthread_struct *st;
st = (pthread_struct*)malloc(sizeof(pthread_struct));
st->id = created;
st->t = newThread;
but newThread does not receive a value until after the successful invocation of pthread_create(). It appears that newThread variable is retaining its previous value on subsequent iterations of the loop, which results in the correct cancelling of all threads except for last thread started as its id is never inserted into the readingThreadsPool array.
You need to populate the st->t member after the call to pthread_create().
As the code currently stands, it is possible for an entry to be inserted into the readingThreadsPool array even though it is not actually a thread yet. Put the insertion logic after the call to pthread_create():
if((threadRes1 =
pthread_create(&(st->t), NULL, pcapReadingThread, (void*)created)))
{
syslog(LOG_CRIT, "Creating Pcap-Reading Thread %d failed.",created);
printf( "Creating Pcap-Reading Thread %d failed.\n",created);
exit(1);
}
pthread_mutex_lock( &mutex_threadsPool );
readingThreadsPool[created] = st;
pthread_mutex_unlock( &mutex_threadsPool );
or if the pcapReadingThread() function accesses readingThreadsPool and expects an entry for itself (which I think might be the case due to created being passed) then enclose the pthread_create() inside the lock of mutex_threadsPool.
I am working on a network programming and I have created a thread pool. It basically has a queue with mutex lock and condition variable and 5 child threads compete to get a work from the queue. It seems like working correctly with locking and unlocking with the condition variable.
But the problems is that if I call a function from the child thread then only one thread is allowed work on the function(fromByte). For example, if thread 1 called the function then the other thread won't be able to enter the function.
void WorkHandler::workLoop(){
printf("WorkHandler::workLoop, called\n");
while(m_workHandlerRun){
Work *work = getWork();
char *pdata = work->getMsg();
/*
* Get type only
*/
unsigned char type = pdata[0];
printf("WorkHandler::workLoop, type %d\n", type);
Packet *packet = m_packetFactory->createInstance(static_cast<PACKET_TYPES>(type));
packet->fromByte(pdata);
}
}
This is the work loop that the child threads are running and it calls the fromByte() after it gets the appropriate class instance from the factory. If I see the log statement then only one thread are allowed to work on the fromByte function and if the thread finished then other thread can work in the function. In other words, if a thread is currently in the function then other threads wait until the thread finish the work.
bool WorkHandler::initThreads(){
for(int i=0; i < m_maxThreads; i++){
pthread_t *thread(new pthread_t);
m_workThreadList.push_back(thread);
if(pthread_create(thread, NULL, runWorkThread, reinterpret_cast<void *>(this))!=0){
perror("WorkHandler::initThreads, pthread_create error \n");
return false;
}
pthread_detach(*thread);
}
return true;
}
This is how I spawn a thread and runWorkThread is a static method to call the workLoop function. How do I fix my code so that child threads can work on the function concurrently. Thanks in advance..
Edit
I am locking and unlocking like this
void WorkHandler::addWork(Work* w){
printf("WorkHandler::insertWork Thread, insertWork locking \n");
lock();
printf("WorkHandler::insertWork Locked, and inserting into queue \n");
m_workQueue.push(w);
signal();
unLock();
}
Work* WorkHandler::getWork(){
printf("WorkHandler::getWork, locking (tid : %lu) \n", pthread_self());
lock();
printf("WorkHandler::getWork, locked (tid : %lu) \n", pthread_self());
while(m_workQueue.empty()){//Need 'while' instead of 'If'
printf("WorkHandler::getWork, waiting... (tid : %lu) \n", pthread_self());
wait();
printf("WorkHandler::getWork, waiting DONE (tid : %lu) \n", pthread_self());
}
Work *work = m_workQueue.front();
printf("WorkHandler::getWork, got a job (tid : %lu) \n", pthread_self());
m_workQueue.pop();
unLock();
return work;
}
Also, this class extends MutexdCondtion class I created
MutexCondition.cpp file
bool MutexCondition::init(){
printf("MutexCondition::init called\n");
pthread_mutex_init(&m_mut, NULL);
pthread_cond_init(&m_con, NULL);
return true;
}
bool MutexCondition::destroy(){
pthread_mutex_destroy(&m_mut);
pthread_cond_destroy(&m_con);
return true;
}
bool MutexCondition::lock(){
pthread_mutex_lock(&m_mut);
return true;
}
bool MutexCondition::unLock(){
pthread_mutex_unlock(&m_mut);
return true;
}
bool MutexCondition::wait(){
pthread_cond_wait(&m_con, &m_mut);
return true;
}
bool MutexCondition::signal(){
pthread_cond_signal(&m_con);
return true;
}
the problem is that if I call a
function from the child thread then
only one thread is allowed work
If you base this assumption on your printf, then you are wrong. It's possible that working thread finishes it's work before new item is placed in queue. This creates possibility, that same function will pick up two items in a row.
There is no way that for other threads to wait for working one, since there is nothing that blocks them after getWork() return.
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM_THREADS 8
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
int taskid, sum;
char *hello_msg;
struct thread_data *my_data;
sleep(1);
my_data = (struct thread_data *) threadarg;
taskid = my_data->thread_id;
sum = my_data->sum;
hello_msg = my_data->message;
printf("Thread %d: %s Sum=%d\n", taskid, hello_msg, sum);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
//int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
messages[1] = "French: Bonjour, le monde!";
messages[2] = "Spanish: Hola al mundo";
messages[3] = "Klingon: Nuq neH!";
messages[4] = "German: Guten Tag, Welt!";
messages[5] = "Russian: Zdravstvytye, mir!";
messages[6] = "Japan: Sekai e konnichiwa!";
messages[7] = "Latin: Orbis, te saluto!";
for(t=0;t<NUM_THREADS;t++) {
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&thread_data_array[t]);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The above piece of code gives me a segmentation fault in linux using gcc
As a beginner I have a few questions in mind regarding threads
If 3 threads are created simultaneously and if they have to exit then the thread that is created first is exitted at the end?
Can the o/p differ every time of a thread creation and termination program and if so why??(I have noticed they do so");
If 3 threads are created simultaneously and if they have to exit then the thread that is created first is exited at the end?
Answer: there is no guarantee that the first thread should exit first. Once they are created, they are treated as separate entities by the OS and it's up to the OS to decide which will exit first.
Can the o/p differ every time of a thread creation and termination program and if so why? (I have noticed they do so);
Answer: yes they do differ, the reason being the same as explained above.
How and when each thread is scheduled is completely upto the OS.
There is no way to understand this without digging deep into the OS code.
In most implementations of pthreads (I have not used all, but all I have used).
When the main thread exits all the other threads stop executing and the application quits.
Thus before exiting the main thread should wait for (or kill) all child threads before exiting.
For this we have pthread_join().
for(t=0;t<NUM_THREADS;t++)
{
void* result;
pthread_join(threads[t],&result);
}
// Now all the children are dead.
Note the underlying io system is not thread safe.
So if multiple threads write to IO then you may potentially get some interleaving.
Your code is working perfectely(I am also using gcc)..
output:
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
Thread 1: French: Bonjour, le monde! Sum=1
Thread 0: English: Hello World! Sum=0
Thread 2: Spanish: Hola al mundo Sum=3
Thread 4: German: Guten Tag, Welt! Sum=10
Thread 3: Klingon: Nuq neH! Sum=6
Thread 5: Russian: Zdravstvytye, mir! Sum=15
Thread 6: Japan: Sekai e konnichiwa! Sum=21
Thread 7: Latin: Orbis, te saluto! Sum=28