I am trying to create a multi-thread, jpg rotation program but I am having problems getting g_thread to work.
int processUserRequest (UserRequest *uRequest,
char * const* argv, int argc, int optind){
struct RotationData CurData;
CurData.argv=argv;
CurData.argc=argc;
CurData.optind=optind;
CurData.uRequest=uRequest;
gpointer user_data = &CurData;
int transform = FALSE;
int max_files = argc - optind;
int i;
gpointer data=&i;
GThreadPool *pool;
if(!g_thread_supported())
g_thread_init(NULL);
pool = g_thread_pool_new(MultiThreadRotation,user_data, 5, TRUE, NULL);
for(i=0;i
{
g_thread_pool_push(pool, &data,NULL);
}
//g_thread_pool_free (pool, TRUE,TRUE);
//Create a montage file
transform = createMontageFile (uRequest);
return transform;
}
The function MultiThreadRotation is suppose to be called by g_thread_pool_push, but it is not being good once. Can anyone help, I am quite the novice.
Also, I thought about outputting the error from g_thread_pool_push, how would you output a GError *error message?
First off, in the code you pasted, there's a bug in the for statement.
Assuming that's fixed, here are a few remarks.
I'm not sure why this is failing, but you can get some indication from the GError's "message" member, which is a human-readable C string you can use with printf() or whatever you like. Unfortunately, you've set the GError arguments to NULL in the g_thread_*() calls.
This routine leaks the thread pool; you should call g_thread_pool_free() before exiting it.
If you're doing other threading in your program, and you care about performance, you should think carefully about whether you want these threads to be exclusive or shared. That's set with the argument to g_thread_pool_new() which you've set to TRUE (exclusive).
Related
I have the following code:
gpointer w[3];
GtkWidget *menu_item = gtk_menu_item_new();
w[0] = menu_item;
menu_item = gtk_menu_item_new();
w[1] = menu_item;
GtkTextBuffer *buffer = gtk_text_buffer_new(NULL);
w[2] = buffer;
This is all good till now. Let's now connect a signal:
g_signal_connect(w[0], "activate", G_CALLBACK(runner), w);
runner function is declared as:
void runner(gpointer root, gpointer w[]);
Testing the values of w array before entering runner and while in it shows that they (the values) are different. I need them to be the same. How can I accomplish that, and why they aren't identical? Also, segfault occurs.
I created a small program that is bare bones of the original one and that is supposed to recreate the conditions such that the problem occurs. Oddly enough, it runs fine.
#include <gtk/gtk.h>
void carry(gpointer root, gpointer a[])
{
g_print("\n");
g_print("%d\n", root);
g_print("%d\n", a[0]);
g_print("%d\n", a[1]);
g_print("%d\n", a[2]);
}
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GtkWidget *menu_item;
GtkTextBuffer *buffer;
gpointer abc[3];
menu_item = gtk_menu_item_new();
abc[0] = menu_item;
g_print("%d\t%d\n", menu_item, abc[0]);
menu_item = gtk_menu_item_new();
abc[1] = menu_item;
g_print("%d\t%d\n", menu_item, abc[1]);
buffer = gtk_text_buffer_new(NULL);
abc[2] = buffer;
g_print("%d\t%d\n", buffer, abc[2]);
g_signal_connect(abc[2], "modified-changed", G_CALLBACK(carry), abc);
gtk_text_buffer_set_modified(abc[2], TRUE);
gtk_main();
return 0;
}
Which means that something else is problematic. I'll try something else now, like commenting lines and leaving only the relevant ones.
I didn't comment any lines yet, but I tried putting g_print in both the caller and the callee.
This is an output:
1162863440 1162863440
1162864736 1162864736
1163320992 1163320992
1162863440
-2
1162668992
973486176
The first three lines compare the original values with their copies in the array (in the sense of g_print("%d\t%d\n", menu_item, abc[0]); from the code above). As you can see, everything is assigned correctly. After a new line, we check those same values in the callee. root, the first parameter, always has the correct value. So there's no problem with that. abc[0] in the callee always has the value of -2. Seriously, every time I run the program it is -2. Other two (abc[1] and abc[2]) always have some garbage random values, but they change every time I run the program unlike abc[0].
I hope this will help in diagnosing and fixing the problem.
I tried passing both abc[0] and abc normally through a function (func(arg0, arg1, ...) instead of using g_signal_connect()) and there is no problem whatsoever.
This all can mean only one thing: g_signal_connect is messing with my values. It changes them for some unknown reason.
I guess I'll have to use a struct.
You're not supposed to use gpointers everywhere. A gpointer is a void *, so you're pretty much disabling all the type checking the compiler could do for you. Use GtkWidget * instead, and do proper casts using G_OBJECT(), GTK_TEXT_BUFFER() etc. macros.
You should also use typed callback arguments, as they appear in the documentation for each signal. For example for the activate signal:
void
user_function (GtkMenuItem *menuitem,
gpointer user_data)
And if you want to pass several items in the user-data field, pass a pointer or pointer to a structure instead of an array of pointers.
And if you have a segfault, well, just use a debugger to check where the problem is.
I would like to create a wrapper for c functions, so that I can convert a function call of the form ret = function(arg1,arg2,arg3); into the form /*void*/ function_wrapper(/*void*/);. That is similar to function objects in C++ and boost bind.
Is this possible? how can I do it?
Update:
To explain in more details what I am looking for:
We start with this function:
int f(int i){
//do stuff
return somevalue;
}
Obvioulsy, it is called like this:
// do stuff
int x = 0;
ret = f(0);
// do more stuff.
I would like to do some magic that will wrap the function into void function(void)
struct function_object fo;
fo.function_pointer = &f;
fo.add_arg(x, int);
fo.set_ret_pointer(&ret);
fo.call();
Note: I saw that there was a vote for closing this question and marking it as unclear. Please do not do that. I have a legitimate need to get this question answered. If you need explanation, ask and I will be glad to elaborate.
I came up with a better code that might allow you to do what you want. First I'll explain how it works, show the code and explain why I still don't think it's a good idea to use it (though the code might open doors for improvements that addresses those issues).
Functionality:
Before you start using the "function objects", you have to call an initialization function (FUNCTIONOBJ_initialize();), which will initialize the mutexes on every data structure used in the library.
After initializing, every time you want to call one of those "function objects", without using the parameters, you will have to set it up first. This is done by creating a FUNCTIONOBJ_handler_t pointer and calling get_function_handler(). This will search for a free FUNCTIONOBJ_handler data structure that can be used at the moment.
If none is found (all FUNCTIONOBJ_handler data structures are busy, being used by some function call) NULL is returned.
If get_function_handler() does find a FUNCTIONOBJ_handler data structure it will try to lock the FUNCTIONOBJ_id_holder data structure, that holds the ID of the FUNCTIONOBJ_handler of the function about to be called.
If FUNCTIONOBJ_id_holder is locked already, get_function_handler() will hang until it's unlocked by the thread using it.
Once FUNCTIONOBJ_id_holder is locked, the ID of the grabbed FUNCTIONOBJ_handler is wrote on it and the FUNCTIONOBJ_handler pointer is returned by get_function_handler.
With the pointer in hand, the user can set the pointer to the arguments and the return variable with set_args_pointer and set_return_pointer, which both take a void * as arguments.
Finally, you can call the function you want. It has to:
1 - Grab the FUNCTIONOBJ_handler ID from the FUNCTIONOBJ_id_holder data structure and use it to get a pointer to the FUNCTIONOBJ_handler itself.
2 - Use the FUNCTIONOBJ_handler to access the arguments.
3 - Return by using one of the return function (on the example we have ret_int, which will return an integer and unlock the FUNCTIONOBJ_handler)
Below is a simplified mind map describing a bit of what is going on:
Finally, the code:
funcobj.h:
#include <stdio.h>
#include <pthread.h>
#define MAX_SIMULTANEOUS_CALLS 1024
typedef struct {
//Current ID about to be called
int current_id;
//Mutex
pthread_mutex_t id_holder_mutex;
} FUNCTIONOBJ_id_holder_t;
typedef struct {
//Attributes
void *arguments;
void *return_pointer;
//Mutex
pthread_mutex_t handler_mutex;
} FUNCTIONOBJ_handler_t;
FUNCTIONOBJ_handler_t FUNCTIONOBJ_handler[MAX_SIMULTANEOUS_CALLS];
FUNCTIONOBJ_id_holder_t FUNCTIONOBJ_id_holder;
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer);
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value);
void FUNCTIONOBJ_initialize(void);
FUNCTIONOBJ_handler_t *get_function_handler(void);
funcobj.c:
#include "funcobj.h"
void set_return_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->return_pointer = pointer;
}
void set_args_pointer(FUNCTIONOBJ_handler_t *this, void *pointer){
this->arguments = pointer;
}
void ret_int(FUNCTIONOBJ_handler_t *this, int return_value){
if(this->return_pointer){
*((int *) (this->return_pointer)) = return_value;
}
pthread_mutex_unlock(&(this->handler_mutex));
}
void FUNCTIONOBJ_initialize(void){
for(int i = 0; i < MAX_SIMULTANEOUS_CALLS; ++i){
pthread_mutex_init(&FUNCTIONOBJ_handler[i].handler_mutex, NULL);
}
pthread_mutex_init(&FUNCTIONOBJ_id_holder.id_holder_mutex, NULL);
}
FUNCTIONOBJ_handler_t *get_function_handler(void){
int i = 0;
while((0 != pthread_mutex_trylock(&FUNCTIONOBJ_handler[i].handler_mutex)) && (i < MAX_SIMULTANEOUS_CALLS)){
++i;
}
if(i >= MAX_SIMULTANEOUS_CALLS){
return NULL;
}
//Sets the ID holder to hold this ID until the function is called
pthread_mutex_lock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
FUNCTIONOBJ_id_holder.current_id = i;
return &FUNCTIONOBJ_handler[i];
}
main.c:
#include "funcobj.h"
#include <string.h>
//Function:
void print(void){
//First the function must grab the handler that contains all its attributes:
//The FUNCTIONOBJ_id_holder is mutex locked, so we can just access its value and
//then free the lock:
FUNCTIONOBJ_handler_t *this = &FUNCTIONOBJ_handler[FUNCTIONOBJ_id_holder.current_id];
//We dont need the id_holder anymore, free it!
pthread_mutex_unlock(&FUNCTIONOBJ_id_holder.id_holder_mutex);
//Do whatever the function has to do
printf("%s\n", (char *) this->arguments);
//Return the value to the pointed variable using the function that returns an int
ret_int(this, 0);
}
void *thread_entry_point(void *data){
int id = (int) data;
char string[100];
snprintf(string, 100, "Thread %u", id);
int return_val;
FUNCTIONOBJ_handler_t *this;
for(int i = 0; i < 200; ++i){
do {
this = get_function_handler();
} while(NULL == this);
set_args_pointer(this, string);
set_return_pointer(this, &return_val);
print();
}
return NULL;
}
int main(int argc, char **argv){
//Initialize global data strucutres (set up mutexes)
FUNCTIONOBJ_initialize();
//testing with 20 threads
pthread_t thread_id[20];
for(int i = 0; i < 20; ++i){
pthread_create(&thread_id[i], NULL, &thread_entry_point, (void *) i);
}
for(int i = 0; i < 20; ++i){
pthread_join(thread_id[i], NULL);
}
return 0;
}
To compile: gcc -o program main.c funcobj.c -lpthread
Reasons to avoid it:
By using this, you are limiting the number of "function objects" that can be running simultaneously. That's because we need to use global data structures to hold the information required by the functions (arguments and return pointer).
You will be seriously slowing down the program when using multiple threads if those use "function objects" frequently: Even though many functions can run at the same time, only a single function object can be set up at a time. So at least for that fraction of time it takes for the program to set up the function and actually call it, all other threads trying to run a function will be hanging waiting the the data structure to be unlocked.
You still have to write some non-intuitive code at the beginning and end of each function you want to work without arguments (grabbing the FUNCTIONOBJ_handler structure, unlocking the FUNCTIONOBJ_id_holder structure, accessing arguments through the pointer you grabbed and returning values with non-built-in functions). This increases the chances of bugs drastically if care is not taken, specially some nasty ones:
Increases the chances of deadlocks. If you forget to unlock one of the data structures in any point of your code, you might end up with a program that works fine at some moments, but randomly freeze completely at others (because all function calls without arguments will be hanging waiting for the lock to be freed). That is a risk that happens on multithreaded programs anyways, but by using this you are increasing the amount of code that requires locks unnecessarily (for style purposes).
Complicates the use of recursive functions: Every time you call the function object you'll have to go through the set up phrase (even when inside another function object). Also, if you call the recursive function enough times to fill all FUNCTIONOBJ_handler structures the program will deadlock.
Amongst other reasons I might not notice at the moment :p
I'm looking for a non invasive way of writing a local variable into a file to use it as a debugging mechanism. The non invasive part means that the debug code should have as little execution time as possible and should minimally interfere with the method that's being debugged.
Example:
Somewhere deep inside the code there is a method.
unsigned int method(short *frame, int length)
{
process-frame(short *frame, int length);
}
It gets called 100 times a second and I would like to print out the content of frame. Since the process is time sensitive I can't print to the terminal but will print into the file in ram. Am looking for a way to do it inside the function scope.
The best I've come so far is this. Am open for other answers with a more optimized approach
unsigned int method(short *frame, int length)
{
static FILE * rawPcmLog;
if (rawPcmLog == NULL) rawPcmLog = fopen("/tmp/rawPcm","w");
int i;
for (i=0; i<length; i++){
fwrite(frame,length, 1,rawPcmLog);
}
process-frame(short *frame, int length);
}
I need to create an instance of my abstract data type, but creating the instance needs some parameters. Now, how should I pass these parameters to the function? There's a lot of parameters, and I would love to have most of them the default value. I see several ways to solve this, however I can not decide which is best.
First option:
MyADT_t *my_adt_create( const char* a_long_config_string);
..where a_long_config_string is a string like "param1=value;param2=value"
This is appealing, but I guess there will be a messy parsing of the string (and error checking) inside the function.
Second option:
MyADT_t *my_adt_create( int paramc, char *paramv[]);
This mimics the command line input style main(int argc, char *argv[]) and could may be implemented with an command line option library, like getopt or popt.
Third option:
Use an variadic function like:
MyADT_t *my_adt_create( int mandatory_param, ...);
..and then in the function read the parameters in pairs of parameter and value. Maybe not much different from second option, but still different.
Additional info: I guess some of the parameters for the factory method will be provided from the command line options. Does this make the choice any simpler?
Edit
To clearify: What if I want my program to launch like this:
myprog --some-general-opt=hello --adt-optinon-a=value --adt-option-b=value
or maybe:
myprog --some-general-opt=hello --adt-options='a_long_config_string'
Another option: use a struct. Pop it in an .h file somewhere, and pass that to the method: that way, you get type-safety, and it's totally obvious to the calling function what's going on.
Example of your struct typedef (uncompiled):
typedef struct {
int size;
char content_flags;
...
} ADT_PARAMS;
Then, in your ADT.c file:
MyADT_t *my_adt_create(ADT_PARAMS *p) {
...
}
To handle the arguments coming in off the command line, there is a getargs function which solves the problem of getting named arguments generally, I personally prefer to knock something up with sscanf, so something like
const char *fmt = "--%s=%s";
int main(int argc, char **argv)
{
int i;
const ADT_PARAMS p = {..default ADT parameters}
for(i = 1; i < argc; i++) {
char *key, *value;
char *cur = *(argv + i);
if(!sscanf(fmt, &key, &value)) {
fprintf(stderr, "Error reading argument: '%s'\n", cur);
return 1;
}
if(!strcmp(key,"some-value")) {
p.some-value = ...
}
}
}
I am very much a novice to C, and I am trying to make a program to run MIDI sequences, and basically, I have two functions, both running a different MIDI pattern, and I need them to run in parallel. Due to the nature of the functions (one running a sequence and the other playing random notes), I am almost 100% sure that I can't have then running in the same function.
I've been scouring the internet for some clue on how to do this with pthreads (which apparently don't work on Windows?) and CreateThread(), but I can't seem to get it to work. I am currently trying to use CreateThread() and trying to bring in the integers required for the random midi sequence and I am getting an error concerning 'LPTHREAD_START_ROUTINE' which reads: 'expected 'LPTHREAD_START_ROUTINE' but argument is of type 'DWORD (*)(int, int, int)'.
A sort of pseudocode of what I'm working on is here:
DWORD WINAPI solo_thread(int key, int tempo, int scale)
{
///// this contains the random midi notes
}
int backing(int key, int tempo, int backing)
{
HANDLE thread = CreateThread(NULL, 0, solo_thread, NULL, 0, NULL);
if (thread) {
////// this contains the midi sequence
}
Hopefully I have explained my problem well... But I am well aware that the most likely case is that I am going about this CreateThread() thing in all the wrong ways.
Thanks!
The signature of the thread entry function is, from the ThreadProc() reference page:
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
and solo_thread() does not have that signature.
If it is necessary to supply multiple arguments to the function create a struct containing multiple members representing the desired arguments. The argument to the thread must outlive the thread otherwise the thread will be accessing a dangling pointer. The common solution is to dynamically allocate the argument and have the thread free() it when it no longer requires it.
Example:
struct Thread_data
{
int key;
int tempo;
int scale;
};
DWORD WINAPI solo_thread(void* arg)
{
struct Thread_data* data = arg;
/* Use 'data'. */
free(data);
return 0;
}
int backing(int key, int tempo, int backing)
{
struct Thread_data* data = malloc(*data);
if (data)
{
data->key = key;
data->tempo = tempo;
data->scale = backing;
HANDLE thread = CreateThread(NULL, 0, solo_thread, &data, 0, NULL);
}