query about few threading terms - arrays

I am understanding and implementing the concept of threading in my application. Since now things are going good. But I have few questions still unanswered and they are making me slow now. I would appreciate if anyone replies to even any of them
In Createthread(), can we only take 1 argument? as I have seen in MSDN website and all other examples that I have seen I saw only 1 argument, LPVOID.
The other thing is , what does the return value DWORD WINAPI means as a return value? Can we have only DWORD , int or any other return type. I suppose it has something to do with HANDLE (may be)
I want to use the array of the thread, hence I learn the array to functions, and (as I have understood) threads are itself just a function called by CreateThread() routine, hence I tried to implement that concept there but could not because of the return type DWORD WINAPI was not allowing me to do so?
I have one single thread for saving files, now I want its array so that I can save multiple files at the same time (not exaclty the same starting time, but sort of parallel file saving). How can I do that?
Thanks
Shan

Indeed, you can only take one argument, of type void * (LPVOID).
However, since it can point to anything, it can point to a struct
or object (usually allocated on the heap for lifetime reasons).
WINAPI is not part of the return value, it's the function's calling
convention. The function must return a DWORD or anything that fit
in it. It must NOT return a pointer, because a pointer can't fit a
DWORD in Win64.
I don't understand, please elaborate what you're
trying to do.
Usually for this you need a single thread function,
passed several times to CreateThread() with a different argument
each time. Don't forget to keep the thread handles (which you'll
likely save in an array) until you stop needing them and close them
with CloseHandle().

for the point number three I guess I understood and will try differently. I was using
DWORD WINAPI save_uwpi_file0( LPVOID )
{
while(1)
{
if(release == 1 && flag_oper1 == 1)
{
int w_cnt = 0; FILE *opfile;
char fname[30] = "txt_file0.txt";
//opening file for write
opfile = fopen(fname , "w");
printf("assigning memory for file 1 \n");
ssint *Lmem = (ssint *)malloc( sizeof(ssint)*size_of_memory);
memcpy(Lmem, pInDMA, sizeof(ssint)*size_of_memory);
release = 0;
printf("relseaing for second file saving\n");
for( int nbr = 0; nbr < size_of_memory; nbr++){
fprintf(opfile , "%hi\n", Lmem[nbr] );
}
printf("aligned free 1\n");
free(Lmem);
fclose(opfile);
printf("File saved 1\n\n");
return 1;
} //if statement ends
}
}
and I was using following to make the pointer to (thread) function
DWORD WINAPI (* save_uwpi_file0)(LPVOID);
I guess I should try something like
DWORD (* save_uwpi_file0)(LPVOID);
I will do it and post the result here

Related

using Dynamic array of HANDLE(void*) with createThread(...)

I'm a beginner in C and in threading in particular.
I need to malloc and use dynamic array of HANDLE that later would be used in WaitForMultipleObjects.
What I do now:
int i = 0 ;
HANDLE ThreadHandlers = (HANDLE)malloc(sizeof(HANDLE)* List->logicalLength);
Then in a loop:
while(curr!= NULL)
{
ThreadHandlers[i]= createtestThread((LPTHREAD_START_ROUTINE)executeTest,(TestStruct*)(curr->data),ThreadIds+i);
curr = curr->next;
//ThreadHandlers[i] =
i++;
}
WaitForMultipleObjects(
List->logicalLength,
ThreadHandlers,
TRUE, /* wait until all threads finish */
INFINITE);
But when I try to compile, it I get:
IntelliSense: expression must be a pointer to a complete object type
Which from my understanding is because HANDLE is typedef void*
and I cant do logic with void*.
What workaround can be done?
What is the right way to do that kind of programming? (waiting for unknown amount of threads)
This line:
HANDLE ThreadHandlers = (HANDLE)malloc(sizeof(HANDLE)* List->logicalLength);
Should be this:
HANDLE* ThreadHandlers = (HANDLE*)malloc(sizeof(HANDLE) * List->logicalLength);
That above fix will resolve your compile problem with regards to WaitForMultipleObjects.
And while I'm here, this line looks suspicous:
ThreadHandlers[i]= createtestThread((LPTHREAD_START_ROUTINE)executeTest,(TestStruct*)(curr->data),ThreadIds+i);
I assume createtestthread is a wrapper for CreateThread or _beginthreadex. But if you have to explicitly cast your function explicitly to LPTHREAD_START_ROUTINE, you have probably done something wrong. Remove the cast such that this line becomes:
ThreadHandlers[i]= createtestThread(executeTest,(TestStruct*)(curr->data),ThreadIds+i);
Then if that still leads to a new compiler error, fix the declaration of executeTest such that it's declared as follows:
DWORD __stdcall executeTest(void* pData);
Forcing a function of a different signature into CreateThread will lead to weird problems later on.
You've made a mistake in creation of array of handles, what you should do is:
HANDLE *ThreadHandlers = (HANDLE*)malloc(sizeof(HANDLE) * List->logicalLength);
As far as your second question goes, using WaitForMultipleObjects is the right way to wait for an unknown amount of threads. Depending on the situation, you could pass FALSE as third parameter if you want to wait only until one thread gets signaled, or pass some time-out interval as fourth argument if you want to stop waiting after a certain period.

How to prevent re-initializing pthread_rwlock_t

I'm declaring array of pthread_rwlock_t static global.
e.g. static pthread_rwlock_t cm[255];
Inside constructor I want to initialize one of the 255 mutex( I keep track with static counter)
Now I'm confused with
1) I don't want to re-initialize lock again, that is bad!
I thought reinitialize should return some error code, but it doesn't:
#include<stdio.h>
#include <pthread.h>
static pthread_rwlock_t cm[2];
int main()
{
int ret;
ret = pthread_rwlock_init(&cm[0], NULL);
ret = pthread_rwlock_wrlock(&cm[0]);
printf("Ret: %d\n", ret);
ret = pthread_rwlock_init(&cm[0], NULL);
printf("Ret: %d\n", ret);
ret = pthread_rwlock_wrlock(&cm[0]);
printf("Ret: %d\n", ret);
}
Result:
Ret: 0
Ret: 0
Ret: 0
Can anyone help, 1) If this is possible, then how? 2) If not what should be alternative approach?
EDIT 1:
I'm updating from comments/answers I got:
Instead, just put the rwlocks inside the objects they protect.
So I have n # of objects getting called, and will be using that many pthread_lock .. so disadvantage is memory. Hence I'm trying to improve on that part with global array of locks. Picking 256 to get good distribution.
It's undefined behavior to call pthread_rwlock_init (or analogously any of the pthread primitive init functions) more than once on the same object, and logically there's no way it would make sense to do so anyway since (as you've demonstrated) the object is already in use. You said in the comments on 2501's answer that you can't use pthread_once, but this makes no sense. If you're able to call pthread_rwlock_init, you can instead just call pthread_once using an init function which performs the call to pthread_rwlock_init.
However I really think you're experiencing an XY problem. There is no sense in maintaining a "global pool" of rwlocks and handing them out dynamically in constructors. Instead, just put the rwlocks inside the objects they protect. If you really want to hand them out from a global pool like you're doing, you need to keep track of which ones have been handed out independently of the job of initializing them, and have the task of initializing them after obtaining one, and destroying one before giving it back to the pool, be handled by the constructor/destructor for the object using them.
If you need static initialization, use PTHREAD_RWLOCK_INITIALIZER on your array.
static pthread_rwlock_t cm[2] = { PTHREAD_RWLOCK_INITIALIZER ,
PTHREAD_RWLOCK_INITIALIZER} ;
This is equivalent as calling pthread_rwlock_init() on every element with attr parameter specified as NULL, except that no error checking is performed.

TCL_LINK_STRING causing segmentation fault (core dumped)

I'm trying to share a variable with c and tcl, the problem is when i try to read the variable in the c thread from tcl, it causes segmentation error, i'm not sure this is the right way to do it, but it seems to work for ints. The part that is causing the segmentation fault is this line is when i try to print "Var" but i want to read the variable to do the corresponding action when the variable changes.
Here is the C code that i'm using
void mode_service(ClientData clientData) {
while(1) {
char* Var = (char *) clientData;
printf("%s\n", Var);
usleep(100000); //100ms
}
}
static int mode_thread(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
Tcl_ThreadId id;
ClientData limitData;
limitData = cdata;
id = 0;
Tcl_CreateThread(&id, mode_service, limitData, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS);
printf("Tcl_CreateThread id = %d\n", (int) id);
// Wait thread process, before returning to TCL prog
int i, aa;
for (i=0 ; i<100000; i++) {aa = i;}
// Return thread ID to tcl prog to allow mutex use
Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id));
printf("returning\n");
return TCL_OK;
}
int DLLEXPORT Modemanager_Init(Tcl_Interp *interp){
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
if (Tcl_PkgProvide(interp, "PCIe", "1.0") == TCL_ERROR) {
return TCL_ERROR;
}
// Create global Var
int *sharedPtr=NULL;
//sharedPtr = sharedPtr = (char *) Tcl_Alloc(sizeof(char));
Tcl_LinkVar(interp, "mode", (char *) &sharedPtr, TCL_LINK_STRING);
Tcl_CreateObjCommand(interp, "mode_thread", mode_thread, sharedPtr, NULL);
return TCL_OK;
}
In the tcl code, i'm changing the variable mode whenever the user presses a button for example:
set mode "Idle"
button .startSamp -text "Sample Start" -width 9 -height 3 -background $btnColor -relief flat -state normal -command {set mode "Sampling"}
set threadId [mode_thread]
puts "Created thread $threadId, waiting"
Your code is a complete mess! You need to decide what you are doing and then do just that. In particular, you are using Tcl_LinkVar so you need to decide what sort of variable you are linking to. If you get a mismatch between the storage, the C access pattern and the declared semantic type, you'll get crashes.
Because your code is in too complicated a mess for me to figure out exactly what you want to do, I'll illustrate with less closely related examples. You'll need to figure out from them how to change things in your code to get the result you need.
Linking Integer Variables
Let's do the simple case: a global int variable (declared outside any function).
int sharedVal;
You want your C code to read that variable and get the value. Easy! Just read it as it is in scope. You also want Tcl code to be able to write to that variable. Easy! In the package initialization function, put this:
Tcl_LinkVar(interp /* == the Tcl interpreter context */,
"sharedVal" /* == the Tcl name */,
(char *) &sharedVal /* == pointer to C variable */,
TCL_LINK_INT /* == what is it! An integer */);
Note that after that (until you Tcl_UnlinkVar) whenever Tcl code reads from the Tcl variable, the current value will be fetched from the C variable and converted.
If you want that variable to be on the heap, you then do:
int *sharedValPtr = malloc(sizeof(int));
C code accesses using *sharedValPtr, and you bind to Tcl with:
Tcl_LinkVar(interp /* == the Tcl interpreter context */,
"sharedVal" /* == the Tcl name */,
(char *) sharedValPtr /* == pointer to C variable */,
TCL_LINK_INT /* == what is it! An integer */);
Linking String Variables
There's a bunch of other semantic types as well as TCL_LINK_INT (see the documentation for a list) but they all follow that pattern except for TCL_LINK_STRING. With that, you do:
char *sharedStr = NULL;
Tcl_LinkVar(interp, "sharedStr", (char *) &sharedStr, TCL_LINK_STRING);
You also need to be aware that the string will always be allocated with Tcl_Alloc (which is substantially faster than most system memory allocators for typical Tcl memory usage patterns) and not with any other memory allocator, and so will also always be deallocated with Tcl_Free. Practically, that means if you set the string from the C side, you must use Tcl_Alloc to allocate the memory.
Posting Update Notifications
The final piece to note is when you set the variable from the C side but want Tcl to notice that the change has set (e.g., because a trace has been set or because you've surfaced the value in a Tk GUI), you should do Tcl_UpdateLinkedVar to let Tcl know that a change has happened that it should pay attention to. If you never use traces (or Tk GUIs, or the vwait command) to watch the variable for updates, you can ignore this API call.
Donal's answer is correct, but I try to show you what you did with your ClientData.
To clarify: All (or almost all, Idk) Tcl functions that take a function pointer also take a parameter of type ClientData that is passed to your function when Tcl calls it.
Let's take a look at this line:
Tcl_CreateObjCommand(interp, "mode_thread", mode_thread, NULL, NULL);
// ------------------------------------------------------^^^^
You always pass NULL as ClientData to the mode_thread function.
In the mode_thread function you use the passed ClientData (NULL) to pass it as ClientData to the new Thread:
limitData = cdata;
// ...
Tcl_CreateThread(&id, mode_service, limitData, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS);
In the mode_service function you use the ClientData (which is still NULL) as pointer to a char array:
char* Var = (char *) clientData;
Which is a pointer to the address 0x00.
And then you tell printf to dereference this NULL pointer:
printf("%s\n", Var);
Which obviously crashes your program.

Behaviour of an hashtable using glib

I want to update the Volume to each #IP. So that for example after each 5 s I add V(i) of each #IP(i). Ok Now the hash table works fine it keeps updated after every T seconds. But the problem is that after a certain period I find that sometimes the same ip adress is repeated twice or even a lot of times within the hash table. So that when I close the process I find the same #IP repeated too many times. It is like there is a problem with the hash table or something like that.
Here is the code this funcion "update_hashTable()" is so important it is called every X seconds I suspect in fact a memory leak ... because I always call malloc for IP#.
but it keeps working ... any idea ???
int update_hashTable( ... ) {
u_int32_t *a;
... //declarations
struct pf_addr *as;
as = ks->addr[0];
a = (u_int32_t*)malloc(sizeof(u_int32_t));
*a = ntohl(as->addr32[0]);
sz = value; // no matter it is... an int for example
if (ReturnValue=(u_int32_t)g_hash_table_lookup(hashtable, a)) {
ReturnValue +=sz;
g_hash_table_insert(hashtable, (gpointer)a, gpointer)ReturnValue);
}
else {
g_hash_table_insert(hashtable, (gpointer)a, (gpointer)sz);
}
Indeed, you appear to have a memory leak, but this isn't your problem. The problem is that the true-path of your if statement simply reinserts a second value associated with the same key, which is not what you want.
The typical pattern for this check-if-exists and increment algorithm is usually something like
gpointer val = g_hash_table_lookup(hash_table, key);
if (val == NULL) {
val = g_malloc0(...);
g_hash_table_insert(hash_table, key, val);
}
*val = /* something */;
The important thing to take away from this is that once you have a pointer to the value associated with some key, you can simply modify it directly.
If this code will be executed by multiple threads in parallel, then the entire block should be protected by a mutex, perhaps with GMutex: http://developer.gnome.org/glib/2.28/glib-Threads.html
gcc provides atomic builtin intrinsics, say for atomically incrementing the value, see http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

SetProp problem

Can anybody tell me why the following code doesn't work? I don't get any compiler errors.
short value = 10;
SetProp(hCtl, "value", (short*) value);
The third parameter is typed as a HANDLE, so IMO to meet the explicit contract of the function you should save the property as a HANDLE by allocating a HGLOBAL memory block. However, as noted in the comments below, MSDN states that any value can be specified, and indeed when I try it on Windows 7 using...
SetProp(hWnd, _T("TestProp"), (HANDLE)(10)); // or (HANDLE)(short*)(10)
...
(short)GetProp(hWnd, _T("TestProp"));
... I get back 10 from GetProp. I suspect somewhere between your SetProp and GetProp one of two things happens: (1) the value of hWnd is different -- you're checking a different window or (2) a timing issue -- the property hasn't been set yet or had been removed.
If you wanted to use an HGLOBAL instead to follow the specific types of the function signature, you can follow this example in MSDN.
Even though a HANDLE is just a pointer, it's a specific data type that is allocated by calls into the Windows API. Lots of things have handles: icons, cursors, files, ... Unless the documentation explicitly states otherwise, to use a blob of data such as a short when the function calls for a HANDLE, you need a memory handle (an HGLOBAL).
The sample code linked above copies data as a string, but you can instead set it as another data type:
// TODO: Add error handling
hMem = GlobalAlloc(GPTR, sizeof(short));
lpMem = GlobalLock(hMem);
if (lpMem != NULL)
{
*((short*)lpMem) = 10;
GlobalUnlock(hMem);
}
To read it back, when you GetProp to get the HANDLE you must lock it to read the memory:
// TODO: Add error handling
short val;
hMem = (HGLOBAL)GetProp(hwnd, ...);
if (hMem)
{
lpMem = GlobalLock(hMem);
if (lpMem)
{
val = *((short*)lpMem);
}
}
I would create the short on the heap, so that it continues to exist, or perhaps make it global, which is perhaps what you did. Also the cast for the short address needs to be void *, or HANDLE.

Resources