c, creating thread and thread function - c

I created dispatch_queue_thread_t struct in the headerfile.
This code assign the thread, task and queue to the dThread struct
dispatch_queue_thread_t *dThread;
dThread = (dispatch_queue_thread_t *) malloc(sizeof(dispatch_queue_thread_t));
pthread_t dispatcher_thread;
if(pthread_create(&dispatcher_thread, NULL, dispatcher_threadloop, (void *)dispatch_queue)){
perror("ERROR creating thread."); exit(EXIT_FAILURE);
}
dThread->task=NULL;
dThread->queue=dispatch_queue;
dThread->thread=dispatcher_thread;
This code is the thread functions for dispatcher_thread.
I need to use thread in dThread to check if there is any task is assigned to it and if not need to assign the task to it.
How do I do that?
Is my code correct?
void *dispatcher_threadloop(void * queue){
//thread loop of the dispatch thread- pass the tast to one of worker thread
dispatch_queue_t *dQueue;
dQueue=queue;
//can I do this?
dispatch_queue_thread_t *dThread;
printf("message-boss1");
dQueue = (dispatch_queue_t *)queue;
if (dQueue->HEAD!=NULL){
for(;;){
sem_wait(dQueue->queue_task_semaphore);
dThread->task = dQueue->HEAD;
dQueue->HEAD = dQueue->HEAD->next;
dQueue->HEAD->prev = NULL;
sem_post(dQueue->queue_task_semaphore);
//TODO
}
}
printf("message-boss2");
}

No. The dThread variable in dispatcher_threadloop() isn't initialised, so it's an error to dereference it.
It seems like you should be passing dThread to the thread function instead of dispatchQueue, as the thread function can obtain the latter from the former. Something like this (note that casting to and from void * is unnecessary):
dispatch_queue_thread_t *dThread;
dThread = malloc(sizeof *dThread);
dThread->task = NULL;
dThread->queue = dispatch_queue;
if (pthread_create(&dThread->thread, NULL, dispatcher_threadloop, dThread)) {
perror("ERROR creating thread.");
exit(EXIT_FAILURE);
}
then in the thread function:
void *dispatcher_threadloop(void *arg)
{
dispatch_queue_thread_t *dThread = arg;
dispatch_queue_t *dQueue = dThread->queue;
/* ... */

Related

Which synchronization primitive should I employ here?

while(1) {
char message_buffer[SIZE];
ssize_t message_length = mq_receive(mq_identifier, message_buffer, _mqueue_max_msg_size NULL);
if(message_len == -1) { /* error handling... */}
pthread_t pt1;
int ret = pthread_create(&pt1, NULL, handle_message, message_buffer);
if(ret) { /* error handling ... */}
}
void * handle_message (void * message) {
puts((char *) message);
return NULL;
}
The above example is not an MRE but it is extremely simple:
I've got a main thread with a loop that constantly consumes messages from a message queue. Once a new message is received, it is stored in the local message_buffer buffer. Then, a new thread is spawned to "take care" of said new message, and thus the message buffer's address is passed into handle_message, which the new thread subsequently executes.
The problem
Often, 2 threads will print the same message, even though I can verify with a 100% certainty that the messages in the queue were not the same.
I am not completely certain, but I think I understand why this is happening:
say that I push 2 different messages to the mqueue and only then I begin consuming them.
In the first iteration of the while loop, the message will get consumed from the queue and saved to message_buffer. A new thread will get spawned and the address of message_length passed to it. But that thread may not be fast enough to print the buffer's contents to the stream before the next message gets consumed (on the next iteration of the loop), and the contents of message_buffer subsequently overridden. Thus the first and second thread now print the same value.
My question is: what is the most efficient way to solve this? I'm pretty new to parallel programming and threading/pthreads and I'm pretty overwhelmed by the different synchronization primitives.
Mutex trouble
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
while(1) {
char message_buffer[SIZE];
pthread_mutex_lock(&m);
ssize_t message_length = mq_receive(mq_identifier, message_buffer, _mqueue_max_msg_size NULL);
pthred_mutex_unlock(&m);
if(message_len == -1) { /* error handling... */}
pthread_t pt1;
int ret = pthread_create(&pt1, NULL, handle_message, message_buffer);
if(ret) { /* error handling ... */}
}
void * handle_message (void * message) {
char own_buffer[SIZE];
pthread_mutex_lock(&m);
strncpy(own_buffer, (char *) message, SIZE);
pthread_mutex_unlock(&m);
puts(own_buffer);
return NULL;
}
I don't think my current mutex implementation is right as the threads are still receiving duplicate messages. The main thread can lock the mutex, consume a message into the buffer, unlock the mutex, spawn a thread, but that thread still may hang and the main one could just rewrite the buffer again (as the buffer mutex was never locked by the new thread), effectively making my current mutex implementation useless? How do I overcome this?
The problem is that you end the loop that contains message_buffer before guaranteeing that the thread has finished with that memory.
while (1) {
char message_buffer[SIZE];
ssize_t message_length = mq_receive(...);
if (message_len == -1) { /* error handling */ }
pthread_t pt1;
int ret = pthread_create(&pt1, NULL, handle_message, message_buffer);
if (ret) { /* error handling */ }
/****** Can't go beyond here until thread is done with message_buffer. ******/
}
void * handle_message (void * message) {
char own_buffer[SIZE];
strncpy(own_buffer, (char *) message, SIZE);
/******* Only now can the caller loop back. ******/
puts(own_buffer);
return NULL;
}
You could use a semaphore or similar.
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int copied = 0;
while (1) {
char message_buffer[SIZE];
ssize_t message_length = mq_receive(...);
if (message_len == -1) { /* error handling */ }
pthread_t pt1;
int ret = pthread_create(&pt1, NULL, handle_message, message_buffer);
if (ret) { /* error handling */ }
// Wait until threads is done with message_buffer.
pthread_mutex_lock(&mutex);
while (!copied) pthread_cond_wait(&cond, &mutex);
copied = 0;
pthread_mutex_unlock(&mutex);
}
void * handle_message (void * message) {
char own_buffer[SIZE];
strncpy(own_buffer, (char *) message, SIZE);
// Done with caller's buffer.
// Signal caller to continue.
pthread_mutex_lock(&mutex);
copied = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
puts(own_buffer);
return NULL;
}
(The added chunks effectively perform semaphore operations. See the last snippet of this answer for a more generic implementation.)
But there's a simpler solution: Make the copy before creating the thread.
while (1) {
char message_buffer[SIZE];
ssize_t message_length = mq_receive(...);
if (message_len == -1) { /* error handling */ }
pthread_t pt1;
int ret = pthread_create(&pt1, NULL, handle_message, strdup(message_buffer));
if (ret) { /* error handling */ }
}
void * handle_message (void * message) {
char * own_buffer = message;
puts(own_buffer);
free(own_buffer);
return NULL;
}

Pthread runtime errors

I'm having trouble debugging the following program I wrote. The idea is to have two seperate threads; one thread executes a 5 second countdown while the other waits for key input from the user. Whichever thread completes first should cancel the sibling thread and exit the program. However, the following code just hangs.
Any help would be appreciated, but I would be most grateful for an explanation as to the problem.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // For sleep()
#define NUM_THREADS 2
// The stuct to be passed as an argument to the countdown routine
typedef struct countdown_struct {
pthread_t *thread;
signed int num_secs;
} CountdownStruct;
// Struct for passing to the input wait routine
typedef struct wait_struct {
pthread_t *thread;
int *key;
} WaitStruct;
// Countdown routine; simply acts as a timer counting down
void * countdown(void *args)
{
CountdownStruct *cd_str = (CountdownStruct *)args;
signed int secs = cd_str->num_secs;
printf("Will use default setting in %d seconds...", secs);
while (secs >= 0)
{
sleep(1);
secs -= 1;
printf("Will use default setting in %d seconds...", secs);
}
// Cancel the other struct
pthread_cancel(*(cd_str->thread));
return NULL;
}
// Waits for the user to pass input through the tty
void * wait_for_input(void *args)
{
WaitStruct *wait_str = (WaitStruct *) args;
int c = 0;
do {
c = getchar();
} while (!(c == '1' || c == '2'));
*(wait_str->key) = c;
// Cancel the other thread
pthread_cancel(*(wait_str->thread));
return NULL;
}
int main(int argc, char **argv)
{
pthread_t wait_thread;
pthread_t countdown_thread;
pthread_attr_t attr;
int key=0;
long numMillis=5000;
int rc=0;
int status=0;
// Create the structs to be passe as paramaters to both routines
CountdownStruct *cd_str = (CountdownStruct *) malloc(sizeof(CountdownStruct));
if (cd_str == NULL)
{
printf("Couldn't create the countdown struct. Aborting...");
return -1;
}
cd_str->thread = &wait_thread;
cd_str->num_secs = 5;
WaitStruct *wait_str = (WaitStruct *) malloc(sizeof(WaitStruct));
if (wait_str == NULL)
{
printf("Couldn't create the iput wait struct. Aborting...");
return -1;
}
wait_str->thread = &countdown_thread;
wait_str->key = &key;
// Create the joinable attribute
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// Create both threads
rc = pthread_create(&countdown_thread, &attr, countdown, (void *) cd_str);
if (rc) { printf("Error with the thread creation!"); exit(-1); }
rc = pthread_create(&wait_thread, &attr, wait_for_input, (void *) wait_str);
if (rc) { printf("Error with the thread creation!"); exit(-1); }
// Destroy the pthread_attribute
pthread_attr_destroy(&attr);
// now join on the threads and wait for main
pthread_join(wait_thread, NULL);
pthread_join(countdown_thread, NULL);
// Call pthread_exit
pthread_exit(NULL);
// Free the function structs
free(cd_str);
free(wait_str);
}
Getchar is not required to be a cancellation point. Select and pselect are. Even if you want to continue to use a countdown thread you could still provide a cancellation point in the opposing thread by use of select.
I had reasonable behavior with the following modified wait_for_input()
// Waits for the user to pass input through the tty
void * wait_for_input(void *args)
{
WaitStruct *wait_str = (WaitStruct *) args;
int c = 0;
fd_set readFds;
int numFds=0;
FD_ZERO(&readFds);
do {
struct timeval timeout={.tv_sec=8,.tv_usec=0};
/* select here is primarily to serve as a cancellation
* point. Though there is a possible race condition
* still between getchar() getting called right as the
* the timeout thread calls cancel.().
* Using the timeout option on select would at least
* cover that, but not done here while testing.
*******************************************************/
FD_ZERO(&readFds);
FD_SET(STDOUT_FILENO,&readFds);
numFds=select(STDOUT_FILENO+1,&readFds,NULL,NULL,&timeout);
if(numFds==0 )
{
/* must be timeout if no FD's selected */
break;
}
if(FD_ISSET(STDOUT_FILENO,&readFds))
{
printf("Only get here if key pressed\n");
c = getchar();
}
} while (!(c == '1' || c == '2'));
*(wait_str->key) = c;
// Cancel the other thread
pthread_cancel(*(wait_str->thread));
return NULL;
}

When creating threads, some are getting a thread ID 0

I have a server application that creates new thread for every incoming request.
However, every once in a while, it will create a thread with thread ID = 0 (used pthread_equal to check this). I have a structure that contains the thread ID that I pass to the function specified in pthread_create, and am checking this there.
Why would a thread get created with ID = 0?
Is there anything I can do if this happens? I cannot use this thread and want to exit it immediately.
=====================================================================
typedef struct
{
pthread_t tid;
other_struct_t Other;
} data_ptr_t;
void * worker(void * arg)
{
data_ptr_t local_data;
data_ptr_t * incoming_data = (data_ptr_t *) arg;
if (NULL == incoming_data || NULL == incoming_data->Other)
{
printf("invalid input\n");
}
else if (pthread_equal(incoming_data->tid, 0))
{
printf("invalid thread id\n");
}
else
{
// add to global thread pool
// do other stuff here
// remove from global thread pool
}
}
int main()
{
// server socket stuff
while (1)
{
// if incoming connection is valid
data_ptr_t data;
int error = pthread_create(&(data.tid), NULL, (void * (*) (void *)) worker, (void *) &data);
if (0 != errror)
{
printf("could not create thread (%d)\n", error);
}
else
{
pthread_detach(data.tid);
printf("thread dispatched\n");
}
}
}
Note: If the number of threads I'm creating is under 50 or so, it works fine. Upwards of 70, most threads go through just fine, the rest end up printing the "invalid thread id".
Note: This is on Linux.
You can't do this:
while (1)
{
// if incoming connection is valid
data_ptr_t data;
int error = pthread_create(&(data.tid),
NULL, (void * (*) (void *)) worker, (void *) &data);
your data_ptr_t is a local variable on the stack. On the next iteration of the while loop, that variable is destroyed/gone/not-valid.
The while loop might start another iteration long before the new worker thread starts running and makes use of the data you pass to it. Instead, dynamically allocate the data you pass to the worker thread so you can be sure it's still valid.

pthread synchronization on two consumers one producer

I have a worker thread processing a queue of work items.
//producer
void push_into_queue(char *item) {
pthread_mutex_lock (&queueMutex);
if(workQueue.full) { // full }
else{
add_item_into_queue(item);
pthread_cond_signal (&queueSignalPush);
}
pthread_mutex_unlock(&queueMutex);
}
// consumer1
void* worker(void* arg) {
while(true) {
pthread_mutex_lock(&queueMutex);
while(workQueue.empty)
pthread_cond_wait(&queueSignalPush, &queueMutex);
item = workQueue.front; // pop from queue
add_item_into_list(item);
// do I need another signal here for thread2?
pthread_cond_signal(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}
pthread_create (&thread1, NULL, (void *) &worker, NULL);
Now I would like to have thread2 consume the data inserted in add_item_into_list() but only if items have been added to the list. Note that the list is permanent and can't be emptied nor freed for the entire duration of the program.
So my question is: do I need another pthread_cond_signal?, if yes, where would this signal go? and how my other worker would look like (canonical form)?
I see 2 possible ways of solving the problem:
a. Introduce another condition variable (e.g. signalList) for the list, so that consumer2 thread would wait for events on it. In this case consumer1 have to signal twice: once on queueSignalPop and once on signalList:
// consumer1
void* worker(void* arg) {
while(true) {
// ...
pthread_cond_signal(&queueSignalPop);
pthread_cond_signal(&signalList);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}
b. Use existing condition queueSignalPop variable inside consumer2 to wait for events, and use broadcast instead of signal inside consumer1. Broadcast means all the waiting threads on condition variable will wake up:
// consumer1
void* worker(void* arg) {
while(true) {
// ...
pthread_cond_broadcast(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}
// consumer2
void* worker2(void* arg) {
while(true) {
while(list.empty)
pthread_cond_wait(&queueSignalPop, &queueMutex);
// ...
}
return NULL;
}
I would propose to go for the first approach, since it better distinguish the purpose of each condition variable.

C pthread_create

typedef struct client
{
pthread thread;
Window_t *win
}client;
client * client_create(int ID)
{
client *new_Client = (client *) malloc(sizeof(client));
char title[16];
if (!new_Client) return NULL;
sprintf(title, "Client %d", ID);
/* Creates a window and set up a communication channel with it */
if ((new_Client->win = window_create(title)))
return new_Client;
else {
free(new_Client);
return NULL;
}
}
When the user inputs 'e' I try to create a new thread with a new client and window by doing this is my int_main.
The flag is just to tell me that the user entered e
if(eflag == 1)
{
client *c = NULL;
c=client_create(started);
pthread_create(&c.thread, NULL, client_create, (void *) &started);
started++;
eflag =0;
}
This is supposed to create a new client on a new thread on a new window but it doesn't do that.
I'm not sure what to put in my pthread_create, and also how am I supposed get a new instance of client, because the client_create function creates a new window. And when I try to create a new thread by doing pthread_create it also creates a new window... If this was java oeverytime the user pressed 'e' I would just create a new instance of the class client... but I can't really do that here. any suggestions?
The prototype of the pthread_create function is
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);
your start_routine definition needs to match void *(*start_routine)(void*).. And it is executed in a new thread context.
void *my_client_routine(void *arg) {
while(1) {
// do what each client does.
}
}
Currently in your main() you are executing your create_client function twice. once before the call to pthread_create() and once as part of the new thread spawned from pthread_create. What you probably want to do is
c = create_client()
pthread_create(&c.thread, NULL, my_client_routine, &args_that_client_routine_needs);

Resources