how one thread can be killed in another thread - pthreads

Actually,the main scenerio is that : from main thread there are two thread running.By using conditional variable,two threads will be running and sleeping and then it will return to main thread.I mean I dont want different output pattern.just one pattern:from main->thread1->thread2->main.
I have written a code for C thread.It shows the result I want sometimes and sometimes not.as for example,the output is:
I am in thread 1
before conditional wait
I am in thread 2
before conditional release
i am again in thread 2
i am again in thread 1
main exits here
The problem is sometimes "main exits here" does not execute.Please help me.It is to be noted that I cant use pthread_join().my code is given below
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t gLock;
pthread_cond_t gCondition;
pthread_mutex_t mLock;
pthread_cond_t mCondition;
void initialize()
{
pthread_mutex_init(&gLock, NULL);
pthread_cond_init (&gCondition, NULL);
pthread_mutex_init(&mLock, NULL);
pthread_cond_init (&mCondition, NULL);
return;
}
void * threadOne(void * msg)
{
printf("%s \n",(char*) msg);
printf("before conditional wait\n");
pthread_mutex_lock(&gLock);
pthread_cond_wait(&gCondition,&gLock);
pthread_mutex_unlock(&gLock);
printf("i am again in thread 1\n");
pthread_mutex_lock(&mLock);
pthread_cond_signal(&mCondition);
pthread_mutex_unlock(&mLock);
}
void * threadTwo(void * msg)
{
printf("%s\n",(char*)msg);
printf("before conditional release\n");
pthread_mutex_lock(&gLock);
pthread_cond_signal(&gCondition);
pthread_mutex_unlock(&gLock);
printf("i am again in thread 2\n");
}
int main()
{
pthread_t thread1;
pthread_t thread2;
char * msg1="I am in thread 1";
char * msg2="I am in thread 2";
initialize();
pthread_create(&thread1,NULL,threadOne,(void*) msg1);
pthread_create(&thread2,NULL,threadTwo,(void*) msg2);
pthread_mutex_lock(&mLock);
pthread_cond_wait(&mCondition,&mLock);
pthread_mutex_unlock(&mLock);
printf("main exits here");
return 0;
}

The problem is that you are using the condition variable incorrectly. A condition variable is just a notification mechanism, not a flag. It has no internal state other than the list of threads currently waiting. Consequently, if main() has not actually executed as far as the pthread_cond_wait() call when the other threads call pthread_cond_signal() then the signal is lost, and main() will wait forever.
You need to use a separate flag associated with the condition variable. main() can then check this flag, and only wait if the flag is not set. Also, it must check this flag in a loop, to ensure that "spurious wakeups" are handled, where pthread_cond_wait() returns without a corresponding signal. The same applies to the notification between threadOne and threadTwo.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t gLock;
pthread_cond_t gCondition;
int gFlag=0;
pthread_mutex_t mLock;
pthread_cond_t mCondition;
int mFlag=0;
void initialize()
{
pthread_mutex_init(&gLock, NULL);
pthread_cond_init (&gCondition, NULL);
pthread_mutex_init(&mLock, NULL);
pthread_cond_init (&mCondition, NULL);
}
void * threadOne(void * msg)
{
printf("%s \n",(char*) msg);
printf("before conditional wait\n");
pthread_mutex_lock(&gLock);
while(!gFlag)
{
pthread_cond_wait(&gCondition,&gLock);
}
pthread_mutex_unlock(&gLock);
printf("i am again in thread 1\n");
pthread_mutex_lock(&mLock);
mFlag=1;
pthread_cond_signal(&mCondition);
pthread_mutex_unlock(&mLock);
}
void * threadTwo(void * msg)
{
printf("%s\n",(char*)msg);
printf("before conditional release\n");
pthread_mutex_lock(&gLock);
gFlag=1;
pthread_cond_signal(&gCondition);
pthread_mutex_unlock(&gLock);
printf("i am again in thread 2\n");
}
int main()
{
pthread_t thread1;
pthread_t thread2;
char * msg1="I am in thread 1";
char * msg2="I am in thread 2";
initialize();
pthread_create(&thread1,NULL,threadOne,(void*) msg1);
pthread_create(&thread2,NULL,threadTwo,(void*) msg2);
pthread_mutex_lock(&mLock);
while(!mFlag)
{
pthread_cond_wait(&mCondition,&mLock);
}
pthread_mutex_unlock(&mLock);
printf("main exits here");
return 0;
}

Related

Understanding of CUDA's cudaGetSymbolAddress

I am new to CUDA, now I'm trying to understand how cudaGetSymbolAddress works. I get an unexpected Segmentation Fault in a really simple code. What I do is the following:
I declare a global device variable(device_int)
In main() I ensure that the definition was correct by setting its value in a kernel
I create a pointer (host_pointer_to_device_int) in host memory and make it point to device_int via cudaGetSymbolAddress
I create one more pointer (host_pointer_to_host_int) and try to cudaMemcpy the value from host_pointer_to_device_int to host_pointer_to_host_int
All these operations finish with no errors, but I get Segmentation Fault when trying to print the host_pointer_to_host_int's value. Here is the code:
#include <iostream>
#include <cassert>
using namespace std;
__device__ int device_int;
__global__ void kernel()
{
device_int = 1000;
}
int main()
{
kernel<<<1, 1>>>();
assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully
int *host_pointer_to_device_int;
cudaGetSymbolAddress((void **)&host_pointer_to_device_int, device_int);
assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully
int *host_pointer_to_host_int;
// Copy the device_int's value
cudaMemcpy((void **)&host_pointer_to_host_int, host_pointer_to_device_int,
sizeof(int), cudaMemcpyDeviceToHost);
assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully
cout << *host_pointer_to_host_int << endl; // Segmentation fault
}
My mistake was not in misunderstanding how cudaGetSymbolAddress works, but in using cudaMemcpy with wrong parameters types: I expected cudaMemcpy to allocate memory for me, so I've cast my variables to the wrong types.
The corrected code is:
#include <iostream>
#include <cassert>
using namespace std;
__device__ int device_int;
__global__ void kernel()
{
device_int = 1000;
}
int main()
{
kernel<<<1, 1>>>();
assert(cudaGetLastError() == cudaSuccess);
int *host_pointer_to_device_int;
/* Get a pointer to device_int. After this, I won't be able to access it,
* but I'm going to copy its value with cudaMemcpy */
cudaGetSymbolAddress((void **)&host_pointer_to_device_int, device_int);
assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully
int host_int;
// Copy the device_int's value
cudaMemcpy(&host_int, host_pointer_to_device_int,
sizeof(int), cudaMemcpyDeviceToHost);
assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully
cout << host_int << endl; // Everything's fine!
}
Thanks to #talonmies for helping me in figuring it out.

Neighbor discovery in contiki

Actually i dont know how to deal with neighbor_recv function. I am not receiving any packet, as was receiving in broadcast-example. All values used in this code are randomly initialized. Moreover I want to store neighbor of each node. Currently I am having 3 telosb motes.
#include "contiki.h"
#include "net/rime/rime.h"
#include "random.h"
#include "node-id.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
#include <stdio.h>
struct adv_msg {
uint16_t val;
};
/*------------------------------------------------------------------------ ---*/
PROCESS(neighbor_process, "Neighbor example");
AUTOSTART_PROCESSES(&neighbor_process);
/*------------------------------------------------------------------------ ---*/
static void
neighbor_recv(struct neighbor_discovery_conn *c, const linkaddr_t *from)
{
printf("message received from %d.%d: '%s'\n",
from->u8[0], from->u8[1], (char *)packetbuf_dataptr());
}
static const struct neighbor_discovery_callbacks cb ={neighbor_recv};
static struct neighbor_discovery_conn neighbor;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(neighbor_process, ev, data)
{
static struct etimer et;
clock_time_t initial=0;// randomly initialize these values
clock_time_t min=0;
clock_time_t max=10;
uint16_t val=108;
PROCESS_EXITHANDLER(neighbor_discovery_close(&neighbor));
PROCESS_BEGIN();
neighbor_discovery_open(&neighbor, 129,initial,min,max,&cb);
while(1) {
/* Delay 2-4 seconds */
etimer_set(&et, CLOCK_SECOND * 4 + random_rand() % (CLOCK_SECOND * 4));
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
packetbuf_copyfrom("Hello", 5);
neighbor_discovery_set_val(&neighbor,val);
neighbor_discovery_start(&neighbor,val);
printf("message sent\n");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

About the parameter of function pthread_create?

We know that we call pthread like this:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void* arg);
Hi guys, i want to know why the return type of third parameter is void*? why not void?
Because there is no way for a start function to know what kind of data a developer wants to return from the function they use a void* that can point to any type. It is up to the developer of the start function to then cast the void* to appropriate type he actually returned before using whatever the void* points to. So now the start function can return a pointer that may in actually point to anything. If the start function is declared to return void, it means this function returns nothing, then what if the developer wants the start function to return a int, a struct? For example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
struct test {
char str[32];
int x;
};
void *func(void*) {
struct test *eg = (struct test *)malloc(sizeof(struct test));
strcpy(eg->str,"hello world");
eg->x = 42;
pthread_exit(eg);
}
int main (void) {
pthread_t id;
struct test *resp;
pthread_create(&id, NULL, func, NULL);
pthread_join(id,(void**)&resp);
printf("%s %d\n",resp->str,resp->x);
free(resp);
return 0;
}
More details on this post: What does void* mean and how to use it?

shared object in pthread

I want to write a sample program in which 16 threads have access to a shared object with huge size like 10gb. I know that I can use pthread_mutex_t to get the lock on the object, but how can I make it efficient so that two or more thread can modify disjoint part of the shared object simultaneously?
Maybe you can create an array of 10 pthread_mutex_t's, one for each 1gb range, and lock the appropriate mutex for the range you'll be modifying?
What about using a sempahore. You can initialize semaphore with number of threads that shares the resources.
/* Includes */
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
#include <semaphore.h> /* Semaphore */
void semhandler ( void *ptr );
sem_t mutex;
int cntr=0; /* shared variable */
int main()
{
int arg[2];
pthread_t thread1;
pthread_t thread2;
arg[0] = 0;
arg[1] = 1;
/* initialize mutex to 2 to share resource with two threads*/
/* Seconds Argumnet "0" makes the semaphore local to the process */
sem_init(&mutex, 0, 2);
pthread_create (&thread1, NULL, (void *) &semhandler, (void *) &arg[0]);
pthread_create (&thread2, NULL, (void *) &semhandler, (void *) &arg[1]);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
sem_destroy(&mutex);
exit(0);
} /* main() */
void semhandler ( void *ptr )
{
int x;
x = *((int *) ptr);
printf("Thrd %d: Waiting to enter critical region...\n", x);
sem_wait(&mutex); /* down semaphore */
if( x == 1 )
cntr++;
/* START CRITICAL REGION */
printf("Thrd %d: Now in critical region...\n", x);
printf("Thrd %d: New Counter Value: %d\n", x, cntr);
printf("Thrd %d: Exiting critical region...\n", x);
/* END CRITICAL REGION */
sem_post(&mutex); /* up semaphore */
pthread_exit(0); /* exit thread */
}

pthread_getspecific and mutex lock

I want to make thread-local buffer for strerror_r call and write my own thread-safe char * my_strerror(int) that will use thread local buffer and call strerror_r.
While reading example regarding pthread_getspecific() in Advanced Programming in Unix Environment by R.Stevens i feel discrepancy - why mutex is used in example below?
Example from book:
#include <limits.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
static pthread_key_t key;
static pthread_once_t init_done = PTHREAD_ONCE_INIT;
pthread_mutex_t env_mutex = PTHREAD_MUTEX_INITIALIZER;
extern char **environ;
static void
thread_init(void)
{
pthread_key_create(&key, free);
}
char *
getenv(const char *name)
{
int i, len;
char *envbuf;
pthread_once(&init_done, thread_init);
pthread_mutex_lock(&env_mutex);
envbuf = (char *)pthread_getspecific(key);
if (envbuf == NULL) {
envbuf = malloc(ARG_MAX);
if (envbuf == NULL) {
pthread_mutex_unlock(&env_mutex);
return(NULL);
}
pthread_setspecific(key, envbuf);
}
len = strlen(name);
for (i = 0; environ[i] != NULL; i++) {
if ((strncmp(name, environ[i], len) == 0) &&
(environ[i][len] == '=')) {
strcpy(envbuf, &environ[i][len+1]);
pthread_mutex_unlock(&env_mutex);
return(envbuf);
}
}
pthread_mutex_unlock(&env_mutex);
return(NULL);
}
The mutex is needed for the protection of the environ variable, for example, from putenv. The lock call is badly placed, though, it's better to be immediately after the strlen.

Resources