According to windows API docs we can use global variable to pass data from creating thread to the new thread and I am assuming the opposite is also possible
Data can also be passed from the creating thread to the new thread using global variables.
Here is a data structure and a callback function, ptr is a pointer to heap allocated memory in main
typedef struct Output
{
char *ptr;
DWORD len;
}Output, *POutput;
Output out; // global variable
DWORD grab_output(LPVOID args)
{
DWORD dread;
BOOL success = FALSE;
while (1)
{
success = ReadFile(g_hChildStd_OUT_Rd,out.ptr, 1024, &dread, NULL);
if (!success || dread == 0 ) break;
out.ptr = realloc(out.ptr, out.len+1024);
out.len += dread;
}
}
int run()
{
BOOL res;
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD dwThreadIdArray[1];
DWORD n_size;
memset(&si, 0 ,sizeof(si));
memset(&pi, 0, sizeof(pi));
memset(&sa, 0, sizeof(sa));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0))
return GetLastError();
if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
return GetLastError();
si.cb = sizeof(STARTUPINFOA);
si.hStdError = g_hChildStd_OUT_Wr;
si.hStdOutput = g_hChildStd_OUT_Wr;
si.dwFlags |= STARTF_USESTDHANDLES;
if(!CreateProcess(NULL,
"C:\\Windows\\System32\\cmd.exe /c dir",
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi
))
{
}
else
{
handle = CreateThread(0, 0, grab_output, NULL, 0, NULL);
}
return 0;
}
int main()
{
out.ptr = malloc(1024);
out.len = 0;
run();
printf("%s\n", out.ptr);
}
when running the code out.ptr returns garbage values
gcc example.c && ./a.exe
└e╔┐═☺
for the sake of this question assume that I will be running a single thread at any given time
The reason this prints garbage values is you assumed for no clear reason that the thread finishes before you accessed the global variable.
There's too many unchecked fault points. Right now, check every function that can error for an error return and produce output in that case, and also set a flag in another global variable. Really, you shouldn't have to, but better to much than not enough. Then close the process and thread handles you aren't using.
Now we should be able to discuss synchronization.
It looks like you want to grab all of the output at once. Thus WaitForSingleObject() on your own thread handle. To produce output incrementally, you need to track input highwater and output highwater and output only the characters in between with putc().
Don't forget to null-terminate your string either, or printf() won't be happy.
You need some means to communicate between the thread and main() that the value has been updated. It is very likely that main() will execute the printf before the thread is done with ReadFile. Also you have a race condition where ReadFile might be writing to the buffer while printf is reading it.
Use a mutex, semaphore, event or similar to communcate between threads, then use WaitForSingleObject etc where appropriate. It's also not advisable to have a busy-loop inside the thread or to exit the creator thread main() while there are threads still running.
EDIT:
Note that you must also return 0 from the thread or your program will go haywire, if you somehow managed to get it compiling in the first place despite the missing return.
Related
I want to simulate Java's behavior of waiting until all threads in the process finish before the main exits in C/Windows API.
The behavior I want to simulate is one of the sample code below(it spams [second thread] active threads: 2., and does not terminate even when main returns):
public final class Test1
{
// | prints current thread count and queues the next iteration.
static void step() {
System.out.println (
"[second thread] active threads: " +
Thread.activeCount() +
"."
);
new Thread(() -> step()).start();
}
public static void main(String[] args) throws Exception
{
// | queue the first iteration.
new Thread(() -> step()).start();
}
}
My initial idea was to completely take over the main of my program, and instead do all the work in another function, eg main2 and if it finishes early, I will wait until the rest of the threads finish.
My problem is that my main has no idea what other threads exist, and even if it did know what other threads existed, after they all finish, it is still possible that they have spawned more threads, that we are again not aware of.
My approach to tackle this looks something as follows:
main.c would contain the actual main, and the actual main logic would be moved out to main2(or something with a better name). main would potentially resort to using CreateToolhelp32Snapshot to discover threads that do not match its own GetThreadId and wait for them(potentially aggregating existing threads to avoid only fetching one existing thread at a time, to take advantage of WaitForMultipleObjects).
/**
* #file main.c
*/
#include <Windows.h>
// | This function will can start threads without worrying about them
// | ending as soon as it finishes.
extern int main2(int argc, char **argv);
// | NOT IMPLEMENTED: I have no idea if such a service exists, but it can probably be
// | implemented using CreateToolhelp32Snapshot.
// | If it did exist, it would return a single thread from the process
// | not matching the current thread id.
extern HANDLE WINAPI SorceryToDiscoverASingleOtherThreadThatExists();
int main(int argc, char **argv)
{
int returnValue;
// | main2 will do the actual main's work.
returnValue = main2(argc, argv);
// | Do not finish before other threads finish.
for (;;) {
HANDLE hThread;
// | Find a single thread handle whose thread id is
// | not the same as the current thread's.
hThread = SorceryToDiscoverASingleOtherThreadThatExists();
// | If there are no more threads,
// | we can finally break out of this infinite loop.
if (hThread == 0) {
break;
}
WaitForSingleObject(hThread, INFINITE);
}
return 0;
}
And main2.c which would behave as our java program would:
/**
* #file main2.c
*/
#include <Windows.h>
#include <stdio.h>
DWORD CALLBACK ThreadProc0001(LPVOID unused) {
puts("Hello, World!");
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
int main2(int argc, char **argv)
{
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
With proof of concept to make sure the above code works(deep_thread_nesting.c):
/**
* #file deep_thread_nesting.c
*/
#include <Windows.h>
#include <stdio.h>
DWORD CALLBACK ThreadProc0001(LPVOID unused) {
puts("Hello, World!");
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
int main(int argc, char **argv)
{
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
// | Do not exit until user presses ctrl c.
for (;;) {
// | Reduce strain on the CPU from the infinite loop.
Sleep(1000);
}
return 0;
}
My problem is that I feel forced to use one of three incredibly ugly solutions:
The first involving the mystical CreateToolhelp32Snapshot function as this tutorial describes, in order to fetch one(or potentially be optimized further to return more than one thread that does not match our active thread id) thread handle(s) that we can use to wait on.
The second involving keeping a global registry of all the handles and having each thread lock the world, add the handle to the registry, remove its own handle, and unlock the world, possibly writing my own CreateThread wrapper that takes care of this for me.
The third being a rough idea, as I have no idea if this even works the way I think it does, hooking the CreateThread function to make all threads implement the second solution.
Question
Is there a way to make C or Windows API wait for all my threads to finish
before terminating the program without effectively writing my own runtime?
Not really an answer, but, as mentioned by IInspectable, ExitProcess is called by the CRT. So getting rid of the CRT the behaviour that you are looking for is restored.
Compile with /NODEFAULTLIB, include libraries using the command line and not #pragma comment(lib, ...).
#include <Windows.h>
DWORD WINAPI other_thread(LPVOID lpThreadParameter)
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if ((hOut == INVALID_HANDLE_VALUE) ||
(!hOut))
{
if (IsDebuggerPresent()) __debugbreak();
return -1;
}
constexpr char string[] = "I am writing!\r\n";
for (;;)
{
WriteFile(hOut, string, sizeof(string), 0, 0);
}
return 0;
}
int mainCRTStartup()
{
HANDLE hThread = CreateThread(0, 0, other_thread, 0, 0, 0);
return 1;
}
The other_thread continues writing, even after the mainCRTStartup exits.
An answer that is closer to what the OP intended:
#include <windows.h>
#pragma comment(lib, "synchronization.lib")
// the program will not (usually) exit, until this counter is at 0
long long deployed_threads_counter;
// we need a place to store the user's function pointer,
// as the lpStartAddress parameter of CreateThread is already used
struct ThreadParameters
{
LPTHREAD_START_ROUTINE lpStartAddress;
LPVOID lpParameter;
};
// a wrapper around the user provided LPTHREAD_START_ROUTINE
DWORD WINAPI my_thread_start(LPVOID lpThreadParameter)
{
// dereferenced! my_create_thread can now exit
ThreadParameters thread_parameters = *(ThreadParameters*)lpThreadParameter;
WakeByAddressSingle(lpThreadParameter);
// actually do the work
BOOL result = thread_parameters.lpStartAddress(thread_parameters.lpParameter);
// signal that the thread has finished executing
InterlockedDecrement64(&deployed_threads_counter);
WakeByAddressSingle(&deployed_threads_counter);
return result;
}
// CreateThread substitude incurs the desired behaviour
HANDLE my_create_thread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId)
{
InterlockedIncrement64(&deployed_threads_counter);
ThreadParameters thread_parameters =
{
lpStartAddress,
lpParameter,
};
// call my_thread_start instead, so that the thread exit is signaled
HANDLE hThread = CreateThread(
lpThreadAttributes,
dwStackSize,
my_thread_start,
&thread_parameters,
dwCreationFlags,
lpThreadId);
// do not destroy thread_parameters, until my_thread_start has finished using them
WaitOnAddress(&thread_parameters, &lpStartAddress, sizeof(LPTHREAD_START_ROUTINE), INFINITE);
return hThread;
}
// optionally set this behaviour to be the default
#define CreateThread my_create_thread
int use_this_main();
int main()
{
// execute user code
int result = use_this_main();
// wait for all threads to finish
while (auto temp = deployed_threads_counter)
{
WaitOnAddress(&deployed_threads_counter, &temp, sizeof(temp), INFINITE);
}
// fallthrough return
return result;
}
int use_this_main()
{
// your code here...
return 0;
}
Currently there is actually a race condition, if InterlockedIncrement64 is called after the main's WaitOnAddress. This can be prevented, with something like a double gate system, but the answer is already complicated enough.
I wish to create a Thread that will always run until I force him to be close.
I programming in c language, and uses the library windows.h
adding my code of creating thread:
HANDLE thread;
DWORD threadID;
thread = CreateThread(NULL, 0, infinitePlay, (void*)*head, 0, &threadID);
if (thread)
{
// doing some work or just waiting
}
In one word (short answer), you need to call the BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode); see microsoft docs in the link term_thread function and pass to it in the hThread param the return thread from CreateThread function in your case it is thread
for long answer
consider the thread function ThreadRoutine below:
#include <windows.h>
DWORD WINAPI ThreadRoutine(void* data) {
/*Creates a thread to execute within the virtual address space of the calling process.
this function will be passed later as a functio pointer to CreateThread which will be the the application-defined function to be executed by the thread.*/
return 0;
}
Now this is the CreateThread function from microsoft_docs
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
__drv_aliasesMem LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Function arguments
lpThreadAttributes: If lpThreadAttributes is NULL, the handle cannot be inherited by child processes.
dwStackSize: The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable.
**lpStartAddress**:
A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. in our case its the ThreadRoutine.
lpParameter: A pointer to a variable to be passed to the thread. we can pass in void* what ever we like to pass since its a generic pointer.
dwCreationFlags: The flags that control the creation of the thread.
lpThreadId: A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.
return value
If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL.
Killing the thread we have created:
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code. DLLs attached to the thread are not notified that the thread is terminating. The system frees the thread's initial stack.
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
So after reviewing all CreateThread arguments, we will use the the form below:
int main() {
HANDLE t_thread = CreateThread(NULL, 0, ThreadRoutine, NULL, 0, NULL);
if (t_thread ) {
// Optionally do stuff, such as wait on the thread or ...
/*After some time lets kill or terminate the thread we have created*/
BOOL re_term =TerminateThread(t_thread , DWORD dwExitCode);
if(re_term == 0){ //failed
/*maybe you should call GetLastError function*/
}
else{
/*killed successefully*/
}
}
return 0;
}
I have a thread called mainloop
i.e.
int run_mainloop;
void* mainloop(void* param)
{
// local vars
// initialize local vars
while(run_mainloop)
{
// run mainloop
}
return 0;
}
The thread is kicked off from a function called client_open, i.e.
int client_open()
{
run_mainloop = 1;
return pthread_create(&thread, NULL, mainloop, NULL);
}
However, in mainloop if initializing local variables fails I need to inform client_open right away of early exit.
pthread_join is inappropriate as it will block and I can't have client_open block.
If it was to wait a short time before returning that would be ok.
How could I do this in a nice way without using pthread_join which will block.
I want to be able to get the return code.
Using pthread_tryjoin_np would be incorrect: the new thread could be arbitrarily delayed between pthread_create return, and the new thread actually executing initialization code.
If you pthread_tryjoin_np during that delay, the join will fail and you will decide that everything is "a-ok", when in fact it isn't.
What you want is a condition: client_open will await on it, and the mainloop will signal it (upon being done with initialization).
You can use something known as completion variables.
Using which a thread can wait till a newly created thread has finished initialization. The only catch is that the new thread must always signal its initialization completion, even when initialization fails.
Something along the following lines (error handling omitted for clarity):
#include <pthread.h>
// Completion variable definition:
typedef struct {
pthread_mutex_t mtx;
pthread_cond_t cnd;
int completed;
int return_code;
} Completion;
#define COMPLETION_INIT { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
int completion_wait(Completion* c) { // add timeout if necessary
pthread_mutex_lock(&c->mtx);
while(!c->completed)
pthread_cond_wait(&c->cnd, &c->mtx);
int return_code = c->return_code;
pthread_mutex_unlock(&c->mtx);
return return_code;
}
void completion_signal(Completion* c, int return_code) {
pthread_mutex_lock(&c->mtx);
c->completed = 1;
c->return_code = return_code;
pthread_cond_signal(&c->cnd);
pthread_mutex_unlock(&c->mtx);
}
// Usage:
void* mainloop(void* vc) {
int init_success = 0;
// initialization
// ...
init_success = 1;
init_end:
Completion* c = (Completion*)vc;
completion_signal(c, init_success); // always signal
if(!init_success)
return NULL;
// start the main loop
return NULL;
}
int client_open()
{
int run_mainloop = 1;
pthread_t thread;
Completion c = COMPLETION_INIT;
pthread_create(&thread, NULL, mainloop, &c);
pthread_detach(thread);
return completion_wait(&c);
}
Ok, I discovered three ways to do this.
1) Initialize and pass variables to mainloop before starting it.
2) Use the Linux specific pthread_tryjoin_np() or pthread_timedjoin_np()
I think the timed join version is more appropriate in this case as it allows time for the thread to be created and for initialisation to be done. The timeout need not be long so it will not block the caller to client_open() for very long.
However, as pointed out by #fge they are non-portable. While that isn't too much of a problem I thought about an alternative way which is this.
EDIT: Not such a good solution, but left in here for reference.
It'd be better to signal to open using a condition variable that initialization was ok.
3) Check if run_mainloop is non-zero, if it is and pthread_create didn't fail and the thread is running. If it's still zero after a time then it didn't start so we call pthread_join to get the exit code.
int run_mainloop = 0;
void* mainloop(void* param)
{
// init vars
// if failure, exit early.
// everything from this point on is good.
run_mainloop = 1;
while (run_mainloop))
{
// do styff
}
return 0;
}
int client_open()
{
void* res;
int rc = pthread_create(&g_thread_id, NULL, mainloop, NULL);
if (rc != 0)
return -1;
usleep(100); // wait a little while, kinda dumb but allows time for init
if (run_mainloop))
return 0;
pthread_join(g_thread_id, &res);
return -1;
}
Im doing a game in C using Threads for windows, but in a point of the game i need to stop some threads in a specific moment, I dont know either the function and the parameters that i need to stop a thread neither what it returns.
This 2 Function are the same, a simple timer that run until the counter reach limit, i want to stop the second thread whenever i want, without using the second parameter of WaitForSingleObject(hThread, Miliseconds).
DWORD WINAPI timer(LPVOID segundo)
{
int counter = 0;
while(counter<segundo)
{
counter++;
gotoxy(30,5);
printf("%d", counter);
Sleep(1000);
}
return NULL;
}
DWORD WINAPI prueba(LPVOID segundo)
{
int counter = 0;
while(counter<segundo)
{
counter++;
gotoxy(30,10);
printf("%d", counter);
Sleep(1000);
}
return NULL;
}
int main()
{
int limit = 5, *ptr;
*ptr = limit;
HANDLE hThread1, hThread2;
DWORD time, probo;
hThread1 = CreateThread(NULL, 0, timer, *ptr, 0, &time);
hThread2 = CreateThread(NULL, 0, prueba, *ptr, 0, &probo);
WaitForSingleObject(hThread2, INFINITE);
WaitForSingleObject(hThread1,INFINITE);
return 0;
}
Create an event using CreateEvent(NULL,FALSE,FALSE,NULL) function, pass this event handle into thread, then in the thread procedure, use WaitForSingleObject(hEvent,1000) instead. Whenever you want to stop the thread, call SetEvent(hEvent), then in the thread proc, do:
DWORD retval = WaitForSingleObject(hEvent,1000);
if( retval != WAIT_TIMEOUT )
return 0;
In C, one usually use a global BOOL, bTerminated, which is initially set to FALSE. The thread repeatedly checks its value, e.g. in your thread function while(counter<segundo && !bTerminated) would be written. Any other part of the code, which wants to stop the thread, should set bTerminated to TRUE, and wait for the thread to stop is needed, by calling WaitForSingleObject. If you have more than one thread, you can use such a logical variable for each thread.
This solution is also the standard approach in Delphi, but in this case the bTerminated variable is a field of the TThread class, and is set to true bay calling the Terminate method. There are similar implementations in C++, too.
Hi I'm creating more than one process with the CreateProcess
and I need to wait all of them to finish, to analyze the results.
And I cant WaitForSingleObject because I need all of the processes running at the same time.
Since each process has a handle at Process_Information (hProcess)
I tought it was ok to use WaitForMultipleObjects,but the parent process ends without waiting for the child.
Is it ok to use WaitForMultipleObjects or there is a better way?
This is how I'm creating the processes:
#define MAX_PROCESS 3
STARTUPINFO si[MAX_PROCESS];
PROCESS_INFORMATION pi[MAX_PROCESS];
WIN32_FIND_DATA fileData;
HANDLE find;
int j=0, t=0;
ZeroMemory(&si, sizeof(si));
for (t = 0; t < MAX_PROCESS; t++)
si[t].cb = sizeof(si[0]);
ZeroMemory(&pi, sizeof(pi));
while (FindNextFile(find, &fileData) != 0)
{
// Start the child process.
if (!CreateProcess(_T("C:\\Users\\Kumppler\\Documents\\Visual Studio 2010\\Projects\ \teste3\\Debug\\teste3.exe"), // No module name (use command line)
aux2, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
TRUE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si[j], // Pointer to STARTUPINFO structure
&pi[j]) // Pointer to PROCESS_INFORMATION structure
)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return;
}
j++;
//find next file related
}
FindClose(find);
WaitForMultipleObjects(MAX_PROCESS, &pi[j].hProcess, FALSE, INFINITE);
//wait and analyze results
Btw I'm trying not to use threads.
WaitForMultipleObjects expects array of handles:
HANDLE hanldes[MAX_PROCESS];
for (int i = 0; i < MAX_PROCESS; ++i)
{
handles[i] = pi[i].hProcess;
}
WaitForMultipleObjects(MAX_PROCESS, handles, TRUE, INFINITE);
Also you should know that maximum array size of handles for WaitForMultipleObjects is limited to MAXIMUM_WAIT_OBJECTS (which is 64).
If you want to wait for all the HANDLEs set 'bWaitAll' (the third parameter) to 'TRUE'.