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.
Related
#include <stdio.h>
#include <process.h>
void sayit(void * arg) {
printf("hello, world! from child process\n");
_endthread();
}
int main(int argc, char ** argv) {
if (_beginthread(sayit, 16, NULL) == -1)
printf("Error\n");
return 0;
}
By idea program must print string in function sayit but it doesn't happen.
Is there any functions to determine had process completed or it still working?
Can you give me links to full documentation for process.h?
You spawn a thread but you don't wait for it. So high chance that the program ends before the second thread is resumed. Use _beginthreadex and WaitForSingleObject or Boost.Threads which have a 'join' function.
When you start a thread in a non-suspended state there is no guarantee when the thread will start so it may just be that the program ends before the thread has started or just as the thread is starting.
In order to make sure the thread runs you need to do something like
unsigned threadID = 0;
HANDLE hd = (HANDLE)_beginthreadex( NULL, 0, sayit, NULL, 0, &threadID);
WaitForSingleObject( hd, INFINITE ); // this will wait for thread to end
CloseHandle(hd);
How can I exit or stop a thread immediately?
How can I make it stop immediately when the user enters an answer?
I want it to reset for every question.
Here's my code where threading is involved
int q1() {
int timer_start;
char ans[] = "lol";
char user_ans[50];
timer_start = pthread_create( &xtimer,NULL,(void*)timer_func,(void*)NULL);
printf("What is the capital city of Peru?\n");
while(limit){
scanf("%s",user_ans);
if(limit)
{
if(!strcmp(user_ans, ans))
{
// printf("YAY!\n");
score++;
// q2();
}
else
{
game_over();
}
}
}
}
You can simply call pthread_cancel on that thread to exit it. And you can send SIGSTOP/SIGCONT signal via pthread_kill to stop/restart it.
But if all you want is a timer, why must you thread?
Based on your code I can give a simple answer:
In this case do not use threads at all.
You do not need them. Store the start time, let the user answer, check the time again after user gives an answer.
{
time_t startTimeSec = time(NULL);
// answering
time_t endTimeSec = time(NULL);
time_t timeTakenSec = endTime-startTime;
if (timeTaken > 10) {
// do your thing
}
}
To answer your question:
You should use a mutex-protected or volatile variable to asynchronously communicate between threads. Set that variable from one thread and check it in another. Then reset its value and repeat. A simple snippet:
int stopIssued = 0;
pthread_mutex_t stopMutex;
int getStopIssued(void) {
int ret = 0;
pthread_mutex_lock(&stopMutex);
ret = stopIssued;
pthread_mutex_unlock(&stopMutex);
return ret;
}
void setStopIssued(int val) {
pthread_mutex_lock(&stopMutex);
stopIssued = val;
pthread_mutex_unlock(&stopMutex);
}
Using pthread_cancel() is an option, but I would not suggest doing it. You will have to check the threads state after this call returns, since pthread_cancel() does not wait for the actual thread stop. And, which to me is even more important, I consider using it ugly.
Using methods to stop a thread is a brute way.
You should rather politely ask the thread to stop by signalling.
Thereby the thread will have an option to tidy after itself e.g. if it has allocated memory, which it will not have any opportunity to do if the thread is cancelled.
The method is relatively simple and comprises no OS signalling:
define a thread state variable or structure outside the thread. Point to it at the pthread_create and dereference the state variable in the thread.
int thread_state = 0; // 0: normal, -1: stop thread, 1: do something
static void *thread_1 (void *arg)
{
int* pthread_state = arg;
... // initialize the thread locals
while(1)
{
switch( *pthread_state )
{
case 0: // normal thread loop
...
break;
case -1:
... // tidy or whatever is necessary
pthread_exit(0); // exit the thread signalling normal return
break;
case 1: //
... // do something special
break;
}
}
}
pthread_create (&t_1, NULL, thread_1, (void*)&thread_state);
...
thread_state = -1; // signal to the thread to stop
// maybe use pthread_exit(0) to exit main.
// this will leave the threads running until they have finished tidy etc.
It is even possible to communicate with the thread using a structure provided that it is simple 'atomic' variables or a simple handshake mechanism is established. Otherwise it may be necessary to use mutex.
Use pthread_join to wait for threads to terminate.
#Naruil's suggestion to call pthread_cancel() is pretty much the best solution i found, but it won't work if you didn't do the following things.
According to the man-page of pthread_cancel the pthread_cancelibility depend on two thing
thread_cancel_state.
thread_cancel_type.
thread_cancel_state is PTHREAD_CANCEL_ENABLE by default, so our main concern is about the thread_cancel_type, it's default value is type PTHREAD_CANCEL_DEFFERED but we need PTHREAD_CANCEL_ASYNCHRONOUS to set on that thread, which we wan't to cancel.
Following an example given::
#include <stdio.h>
#include <pthread.h>
void *thread_runner(void* arg)
{
//catch the pthread_object as argument
pthread_t obj = *((pthread_t*)arg);
//ENABLING THE CANCEL FUNCTIONALITY
int prevType;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &prevType);
int i=0;
for( ; i < 11 ; i++)//1 - > 10
{
if(i == 5)
pthread_cancel(obj);
else
printf("count -- %d", i);
}
printf("done");
}
int main(int argc, char *argv[])
{
pthread_t obj;
pthread_create(&obj, NULL, thread_runner, (void*)&obj);
pthread_join(obj, NULL);
return 0;
}
run it using gcc filename.c -lpthread and output the following::
count -- 0
count -- 1
count -- 2
count -- 3
count -- 4
note that the done is never printed because the thread was canceled when the i became 5 & the running thread was canceled. Special thanks #Naruil for the "pthread_cancel" suggestion.
The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?
Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.
Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :
#include <stdint.h>
#include <pthread.h>
#include <event.h>
void * thread_func (void *);
int main(void)
{
int32_t tid = 0, ret = -1;
struct event_base *evbase;
struct event *timer;
int32_t *t_ret = &ret;
struct timeval tv;
// 1. initialize libevent for pthreads
evthread_use_pthreads();
ret = pthread_create(&tid, NULL, thread_func, NULL);
// check ret for error
// 2. allocate event base
evbase = event_base_new();
// 3. allocate event object
timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
// 4. add event
tv.tv_sec = 0;
tv.tv_usec = 1000;
evtimer_add(timer, &tv);
// 5. start the event loop
event_base_dispatch(evbase); // event loop
// join pthread...
// 6. free resources
event_free(timer);
event_base_free(evbase);
return 0;
}
void * thread_func(void *arg)
{
struct event *ev;
struct event_base *base;
base = event_base_new();
ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
event_add(ev, NULL); // wait forever
event_base_dispatch(base); // start event loop
event_free(ev);
event_base_free(base);
pthread_exit(0);
}
As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :
call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
Schedule the event for execution
Start the event loop
free the resources when done.
Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.
cheers.
That would work.
In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.
To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread
wakes up and read the pointer from the pipe.
There is a multithreaded libevent example in this blog post:
http://www.roncemer.com/multi-threaded-libevent-server-example
His solution is, to quote:
The solution is to create one libevent event queue (AKA event_base) per active connection, each with its own event pump thread. This project does exactly that, giving you everything you need to write high-performance, multi-threaded, libevent-based socket servers.
NOTE This is for libev not libevent but the idea may apply.
Here I present an example for the community. Please comment and let me know if there are any noticable bugs. This example could include a signal handler for thread termination and graceful exit in the future.
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//compile using: gcc -g test.c -o test -lpthread -lev
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
// now wait for events to arrive on the inner loop
ev_loop(loop2, 0);
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if(ev_async_pending(&async_watcher)==false){ //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive on the main loop
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
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.