below is C snippet from mongoose webserver http event handler I am working on:
static void HttpEventHandler(struct mg_connection *nc, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_REQUEST) {
struct http_message *hm = (struct http_message *) ev_data;
if (mg_vcmp(&hm->method, "POST") == 0) {
pthread_t thread_id;
int rc;
rc = pthread_create(&thread_id, NULL, thr_func, /* Here I want hm body to be passed after its malloced */);
if (rc) { /* could not create thread */
fprintf(stderr, "error: pthread_create, rc: %d\n", rc);
return EXIT_FAILURE;
}
}//if POST
mg_printf(nc, "HTTP/1.1 200 OK\r\n");
nc->flags |= MG_F_SEND_AND_CLOSE;
}
}
the http post message body, accessible as string using below syntax:
"%.*s", (int) hm->body.len,hm->body.p
I want code sample to malloc hm->body and pass it to the thread in snippet above, also it would be great to explain how to cast the passed void *. if its difficult then please malloc ev_data or hm.
You'd malloc() it as in:
hm->body = malloc(sizeof *(hm->body));
hm->body.p = "string";
/* The above assigns a string literal. If you need to copy some
user-defined string then you can instead do:
hm->body = malloc(size); strcpy(hm->body.p, str);
where 'str' is the string you want copy and 'size' is the length of 'str'.
*/
hm->body.len = strlen(hm->body);
and then pass it to:
rc = pthread_create(&thread_id, NULL, thr_func, hm->body);
In thr_func() you would need to convert the argument to whatever the type of hm->body and then access it (because void * can't be dereferenced directly.). Something like:
void *thr_func(void *arg)
{
struct mg_str *hm_body = arg;
printf("str: %s, len: %zu\n", hm_body->p, hm_body->len);
...
return NULL;
}
There's no need to cast anything to void*. The pthread_create() API expects a void * as the last argument and any data
pointer can be directly assigned to void *. The same applies to struct http_message *hm = (struct http_message *) ev_data; statement as well.
It can be just: struct http_message *hm = ev_data;.
Depending how the "webserver" is implemented, you might need to take care of thread(s) completion as well.
P.S: If you show the "hm" structure, it'll be much easier to explain things.
Related
I am working on an assignment which requires me to use threads to process and synchronize fetching data from a file. My professor told me that I can change my data to a void pointer to pass it to my function and then cast it back. I am trying to do this with file IO.
pthread_create(&th1, NULL, processing, (void *)&fp);
In my processing function I am trying to cast it back to a FILE pointer with this:
FILE driveOne = (FILE *)file;
This clearly doesn't work, so can someone explain this to me?
Here's a more complete example.
Let's say your worker function needs a file handle. For simplicity, let's say it reads each char from it, and returns the number of chars read, cast to a pointer:
void *worker(void *data)
{
FILE *handle = (FILE *)data;
uintptr_t count = 0;
if (handle && !ferror(handle)) {
/* handle is a valid file handle */
while (getc(handle) != EOF)
count++;
}
return (void *)count;
}
If count were of some other type than intptr_t or uintptr_t (declared in <stdint.h>, which is typically included by including <inttypes.h>), you'd need to cast it first to that type, and then to void pointer, i.e. (void *)(uintptr_t)count.
Because such worker threads don't need much stack (almost none, to be precise), and default thread stack sizes are huge (megabytes), we can save some memory (and allow much more threads if needed, especially on 32-bit architectures) by creating a pthread attribute that instructs pthread_create() to use a smaller stack. This attribute is not "consumed" by the call; it is more like an configuration block.
Let's say you have three streams, FILE *in[3];, and you wish to use three threads to check their lengths. Using a pthread attribute to use a smaller stack (2*PTHREAD_STACK_MIN, as defined in <limits.h>, is a good, safe value for worker threads that don't use alloca() or local arrays.):
pthread_t worker_id[3];
uintptr_t length[3];
pthread_attr_t attrs;
void *retptr;
int i, result;
/* Create a pthread attribute set, defining smaller stack size. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);
/* Create the three worker threads. */
for (i = 0; i < 3; i++) {
result = pthread_create(&(worker_id[i]), &attrs, worker, (void *)in[i]);
if (result) {
fprintf(stderr, "Cannot create thread: %s.\n", strerror(result));
exit(EXIT_FAILURE);
}
}
/* pthread attributes are no longer needed. */
pthread_attr_destroy(&attrs);
/*
... This thread can do something else here ...
*/
/* Reap the threads, and collect their return values. */
for (i = 0; i < 3; i++) {
result = pthread_join(worker_id[i], &retptr);
if (result) {
fprintf(stderr, "Cannot reap thread: %s.\n", strerror(result));
exit(EXIT_FAILURE);
}
length[i] = (uintptr_t)retptr;
}
for (i = 0; i < 3; i++)
printf("in[%d] contained %llu chars.\n", i, (unsigned long long)length[i]);
The same pattern can be used when you want to pass multiple parameters to the thread function. You first construct a structure to hold those parameters, and create them. You can allocate them dynamically, declare them as global variables, or declare them as local variables in main() -- any scope that exists for the full duration when the worker thread exists, works.
For example, let's say your worker function calculates a histogram of each unsigned char value it reads from the stream:
struct work {
pthread_t id; /* Thread identifier */
FILE *in; /* File handle to read from */
size_t count[UCHAR_MAX + 1]; /* Histogram */
};
void *worker(void *data) {
struct work *const work = (struct worker_data *)data;
int c;
if (!work || !work->in) {
/* Invalid data, or invalid file handle. */
return (void *)(intptr_t)(EINVAL);
}
if (ferror(work->in)) {
/* Stream is in error state. */
return (void *)(intptr_t)(EIO);
}
/* Read the stream. */
while ((c = getc(work->in)) != EOF) {
/* Update histogram. */
work->count[(unsigned char)c]++;
}
/* Did the reading stop due to an I/O error? */
if (ferror(work->in))
return (void *)(intptr_t)(EIO);
/* No errors, all done. */
return (void *)0;
}
Note that struct work *const work = ... initializes a constant pointer work, not a pointer to constant. The const there is just an optimization that tells the C compiler that we won't try to modify work pointer itself. The data it points to, is modifiable.
(To read pointer declarations, read them from right to left, replacing each * with "is a pointer to", to get the proper sense of it.)
The code to create these workers is very similar, except that we allocate the work dynamically:
struct work *work[3];
pthread_attr_t attrs;
void *retptr;
int i, result;
/* Create and initialize the three pointers. */
for (i = 0; i < 3; i++) {
/* Allocate a work structure. */
work[i] = malloc(sizeof *(work[i]));
if (!work[i]) {
fprintf(stderr, "Out of memory.\n");
exit(EXIT_FAILURE);
}
/* Copy the handle to read from, */
work[i]->in = in[i];
/* and clear the histogram part. */
memset(work[i]->count, 0, sizeof work[i]->count);
}
/* Create a pthread attribute set, defining smaller stack size. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, 2*PTHREAD_STACK_MIN);
/* Create the three worker threads. */
for (i = 0; i < 3; i++) {
result = pthread_create(&(work[i]->id), &attrs, worker, (void *)work[i]);
if (result) {
fprintf(stderr, "Cannot create thread: %s.\n", strerror(result));
exit(EXIT_FAILURE);
}
}
/* pthread attributes are no longer needed. */
pthread_attr_destroy(&attrs);
/*
... This thread can do something else here ...
*/
/* Reap the threads, and collect their return values. */
for (i = 0; i < 3; i++) {
result = pthread_join(work[i]->id, &retptr);
if (result) {
fprintf(stderr, "Cannot reap thread: %s.\n", strerror(result));
exit(EXIT_FAILURE);
}
/* If the thread reported a failure, print the corresponding
error message (but do not exit). */
if (retptr)
fprintf(stderr, "Thread %d of 3: %s.\n", i+1, strerror((intptr_t)retptr));
/* ... print the histogram here? ... */
}
/* Free the work structures. */
for (i = 0; i < 3; i++)
free(work[i]);
If you don't want to abort the program when an error occurs, it is useful to note that free(NULL) is safe and does nothing; and that struct work *pointerarray[SIZE] = {0}; declares an array of SIZE pointers to struct work, and initializes them all to zero. For example, if an allocation or thread creation fails at some point, you can just free() each pointer, whether or not its allocation was successful.
That is, if you want to allocate three different types of structures (struct atype *a;, struct btype *b;, and struct ctype *c;), you can do
a = malloc(sizeof *a);
b = malloc(sizeof *b);
c = malloc(sizeof *c);
if (!a || !b || !c) {
free(c);
free(b);
free(a);
return ALLOCATION_FAILED;
}
/* Allocation was successful */
instead of allocating each one and testing for failure separately.
You need to declare driveOne to be FILE *, not FILE.
FILE *driveOne = (FILE *)file;
In addition, assuming that fp was initially declared as FILE *, your call to pthread_create should not have & before fp, like so:
pthread_create(&th1, NULL, processing, (void *)fp);
I write generic application for handle as many modbus devices as defined in JSON config file.
mbus_servers struct used in my_modbus_init() contents ip of device and port.
Initialization of one modbus_t in my_modbus_init() looks like this:
modbus_t * my_modbus_init(const char * ip_s, int port, int slave_id)
{
modbus_t *ctx;
ctx = modbus_new_tcp(ip_s, port);
if(ctx == NULL)
{
printf("Error");
}
modbus_set_debug(ctx, 0);
if (modbus_connect(ctx) == -1)
{
fprintf(stderr, "Connection failed: %s\n",modbus_strerror(errno));
modbus_free(ctx);
return NULL;
}
modbus_set_slave(ctx, slave_id);
return ctx;
}
Now I try to initialize dynamiclly allocated number of modbus_t:
modbus_t * my_modbus;
int quantity_of_connections_modbus = 3;
my_modbus = (modbus_t *) malloc (quantity_of_connections_modbus * sizeof(modbus_t));
^here I get invalid application of ‘sizeof’ to incomplete type ‘modbus_t' (I know that is because i dont have acces to definition of modbus_t [it is defined in modbus.h as typedef struct _modbus modbus_t; ])
for(i=0; i< quantity_of_connections_modbus; i++)
{
// |> my_modbus[i] = my_modbus_init(mbus_servers[i]->host,mbus_servers[i]->port,MBUS_SLAVE);
// |- And here error: dereferencing pointer to incomplete type ‘modbus_t {aka struct _modbus}’
}
Is there any way to create as many modbus_t as needed using malloc?
Instead of having an array of modbus_t objects, have an array of pointers to modbus_t objects. This makes sense since the my_modbus_init function (and the modbus_new_tcp function it calls) returns pointers.
In other words change sizeof(modbus_t) to sizeof(modbus_t *). And change the variable my_modbus to represent this array of pointers (i.e. be a modbus_t **).
The code from the question modified accordingly:
modbus_t ** my_modbus;
int quantity_of_connections_modbus = 3;
my_modbus = malloc (quantity_of_connections_modbus * sizeof(modbus_t*));
for(i=0; i< quantity_of_connections_modbus; i++)
{
my_modbus[i] = my_modbus_init(mbus_servers[i]->host,mbus_servers[i]->port,MBUS_SLAVE);
}
I would like to run my thread simultaneously as my main program. How do I do so? Currently the thread is running a never ending loop, but i would like it to run at the same time as when my main program continues running. Here is my code.
This is my thread:
void *LEDReadingsTimer(char *buffer, int clientSocket) //void *arg
{
while(timer!=0)
{
delay(2000);
LEDReadings(buffer, clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
Here is my main code:
timer=1;
wiringPiSetupSys () ;
gertboardAnalogSetup (100) ;
pthread_create(&tid, NULL, LEDReadingsTimer(buffer,clientSocket), NULL);
//Receive and send data from and to Android
while(1){
nread = recv(clientSocket,buffer,4096,0);//recvfrom(clientSocket, buffer,1024, 0, (struct sockaddr *) &serverStorage, &addr_size);
buffer[nread] = '\0';
if((atof(buffer)>=0)&&(atof(buffer)<=1)){
printf("Data Received: %s\n", buffer);
LEDBrightness(buffer);
//LEDReadings(buffer, clientSocket);
}
This is my LEDReadings function.
int LEDReadings(char *buffer, int clientSocket){
int x1, x2 ;
double v1, v2 ;
double a;
printf ("| Channel 0 | Channel 1 |\n") ;
// Read the 2 channels:
x1 = analogRead (100) ; //voltage
x2 = analogRead (101) ; //current
// Convert to a voltage:
v1 = (double)x1 / 1023.0 * 3.3 ;
v2 = (double)x2 / 1023.0 * 3.3 ;
a = v2*30;
printf ("%6.3f|%6.3f\n", v1, a) ;
fflush (stdout) ;
snprintf(buffer, 4096,"%6.3fsplit%6.3f\n", v1, a);
send(clientSocket,buffer,strlen(buffer)+1,0);
return 0;
}
Once my pthread runs, it doesn't go into the next while loop to do recv function.
I assume you know you have to pass pthread_create() a function pointer. There's no such thing in C as a "function pointer with arguments", it's just the address of the function. So what you do here is just call a function the normal way, this function never returns, so the pthread_create() is never executed, waiting for evaluation of one of its arguments.
Have a look at the prototype of pthread_create():
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
This means your start_routine must accept and return void *. So you have to change the signature of your function to
void *LEDReadingsTimer(void *args);
Now, how do you pass the parameters? Simply use a struct. Define this struct somewhere:
struct LEDReadingsTimerArgs
{
char *buffer;
int clientSocket;
};
Then you can change your thread function to this:
void *LEDReadingsTimer(void *args)
{
struct LEDReadingsTimerArgs *lrtArgs = args;
while(timer!=0)
{
delay(2000);
LEDReadings(lrtArgs->buffer, lrtArgs->clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
The last argument of pthread_create is for passing the arguments, so start your thread like this:
struct LEDReadingsTimerArgs lrtArgs = {buffer, clientSocket};
pthread_create(&tid, NULL, LEDReadingsTimer, &lrtArgs);
You are calling the thread function yourself rather than giving it to pthread_create as a pointer. This means the function will run forever and no thread will ever be created.
You need to create a way to pass parameters, for example a struct
struct params
{
char *buffer;
int clientSocket;
}
Then you change your thread function into one that gets it as a parameter
void *LEDReadingsTimer(void *args)
{
struct params *pars = args;
while(timer!=0)
{
delay(2000);
LEDReadings(pars->buffer, pars->clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
And in your main function you define a struct, set values and pass it to the thread funtion through pthread_create;
struct params pars;
pars.buffer = buffer;
pars.clientSocket = clientSocket;
pthread_create(&tid, NULL, LEDReadingsTimer, &pars);
This way your thread function is called by pthread and the parameters you pass to it will be usable from the thread. Of course always make sure the parameter struct doesn't go out of scope and get freed while the thread is running.
I have the following code:
for(i = 0 ; i < max_thread; i++)
{
struct arg_struct args;
args.arg1 = file;
args.arg2 = word;
args.arg3 = repl;
if(pthread_create(&thread_id[i],NULL,&do_process,&args) != 0)
{
i--;
fprintf(stderr,RED "\nError in creating thread\n" NONE);
}
}
for(i = 0 ; i < max_thread; i++)
if(pthread_join(thread_id[i],NULL) != 0)
{
fprintf(stderr,RED "\nError in joining thread\n" NONE);
}
int do_process(void *arguments)
{
//code missing
}
*How can I transform (void *)do_process into (int) do_process ?*
That function returns very important info and without those returns I don't know how to read the replies
I get the following error: warning: passing arg 3 of `pthread_create' makes pointer from integer without a cast
The thread function returns a pointer. At minimum, you can allocate an integer dynamically and return it.
void * do_process (void *arg) {
/* ... */
int *result = malloc(sizeof(int));
*result = the_result_code;
return result;
}
Then, you can recover this pointer from the thread_join() call;
void *join_result;
if(pthread_join(thread_id[i],&join_result) != 0)
{
fprintf(stderr,RED "\nError in joining thread\n" NONE);
} else {
int result = *(int *)join_result;
free(join_result);
/* ... */
}
Just write a helper function that is of the correct type, but all it does is take the void * input parameter, get all the right parameters out of it, call your function, take the return of that, and package it up as a void * for pthread_join to get.
To your specific question, you can't/shouldn't. Just do what I outlined above and you'll be golden.
The pthread_join() is a simple way to communicate between the two threads. It has two limitations. First, it can pass only one value from the pointer (you can make it a pointer and store multiple values). Second, you can return it only when the thread is all done -- after returning this value, the thread goes in terminated state. So, if you want the threads to communicate in a more granular fashion, you will be better served in using a common shared data. Of course, at teh very least, you would to use Pthread mutex to synchronize access to the common data. And, if you want the threads to communicate with each other, then you would also need to use Pthread condvars.
Code:
struct company_struct
{
company_name_t company_name;
double stock_price;
company_stock_t company_stock;
};
typedef struct company_struct company_struct_t;
int sort_by_price(const void * ptr1, const void * ptr2)
{
assert(ptr1 != NULL);
assert(ptr2 != NULL);
const company_struct_t * ptr1_price = (const company_struct_t *) ptr1;
const company_struct_t * ptr2_price = (const company_struct_t *) ptr2;
assert(ptr1_price->stock_price != NULL); //??? Why it failed?
assert(ptr2_price->stock_price != NULL);
if(ptr1_price->stock_price > ptr2_price->stock_price) return -1;
else if (ptr1_price->stock_price == ptr2_price->stock_price) return 0;
else if (ptr1_price->stock_price < ptr2_price->stock_price) return 1;
}
qsort(company_list, *size, sizeof(company_list), sort_by_price);
When I run my program, the assert failed. I am relatively new to C, please bear with me.
You need to pass the size of an individual element as the third parameter of qsort, like this:
qsort(company_list, *size, sizeof(company_struct_t), sort_by_price);
Also make sure that size points to an int that holds the number of items to be sorted.
If it really is this line that's failing,
assert(ptr1_price->stock_price != NULL); //??? Why it failed?
you should crank-up your compiler warnings. You should get a warning for comparing a double to a pointer. [And for prices, it's usually better to use an integer. What would $0.000003 mean?]