Does ThreadFunc() gets called two times here? sometimes I notice a single call and sometimes none at all.
#include <windows.h>
#include <stdio.h>
DWORD WINAPI ThreadFunc(LPVOID);
int main()
{
HANDLE hThread;
DWORD threadld;
hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, &threadld );
printf("Thread is running\n");
}
DWORD WINAPI ThreadFunc(LPVOID p)
{
printf("In ThreadFunc\n");
return 0;
}
Output 1
Thread is running
In ThreadFunc
In ThreadFunc
Press any key to continue . . .
Output 2
Thread is running
In ThreadFunc
Press any key to continue . . .
Output 3
Thread is running
Press any key to continue . . .
In order to call CRT functions, such as printf you should use _beginthread or _beginthreadex instead of CreateThread.
Anyway, the program may end before the thread has the opportunity to output anything.
A little addition: use WaitForSingleObject inside main() to give your thread finish a job.
No, ThreadFunc should never get called twice. In any case, I believe your code snippet is incomplete - could you post the full code snippet where you are seeing this problem?
Related
I am using VS 2022 Preview to write a C++ console application. I wish to detect a keyboard hit and have my interrupt handler function called. I want the key press detected quickly in case main is in a long loop and therefore not using kbhit().
I found signal() but the debugger stops when the Control-C is detected. Maybe it is a peculiarity of the IDE. Is there a function or system call that I should use?
Edit: I am vaguely aware of threads. Could I spawn a thread that just watches kbd and then have it raise(?) an interrupt when a key is pressed?
I was able to do it by adding a thread. On the target I will have real interrupts to trigger my ISR but this is close enough for algorithm development. It seemed that terminating the thread was more trouble than it was worth so I rationalized that I am simulating an embedded system that does not need fancy shutdowns.
I decided to just accept one character at a time in the phony ISR then I can buffer them and wait and process the whole string when I see a CR, a simple minded command line processor.
// Scheduler.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <Windows.h>
#include <iostream>
#include <thread>
#include <conio.h>
void phonyISR(int tbd)
{
char c;
while (1)
{
std::cout << "\nphonyISR() waiting for kbd input:";
c = _getch();
std::cout << "\nGot >" << c << "<";
}
}
int main(int argc, char* argv[])
{
int tbd;
std::thread t = std::thread(phonyISR, tbd);
// Main thread doing its stuff
int i = 0;
while (1)
{
Sleep(2000);
std::cout << "\nMain: " << i++;
}
return 0;
}
I tried to write simple fork-and-exec application with the following code
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
int
spawn(char *program, char *arg_list[])
{
pid_t child_pid;
child_pid = fork();
if (child_pid != 0)
return child_pid;
else {
execvp(program, arg_list);
fprintf(stderr, "an error occured\n");
exit(EXIT_FAILURE);
}
}
int
main()
{
int child_stat;
char *arg_list[] = {
"ls",
"-l",
"/",
NULL
};
spawn("ls", arg_list);
printf("return to parent\n");
return 0;
}
Every goes fine, but child after becoming ls does not terminate.
Shell looks like
./main
return to parent
-- ls output here --
But command prompt does not appear, so I assume that one process hangs and the reason is not obvious for me. Can you, please, point to my mistake.
Thanks in advance.
I believe that it works correctly. However, the order of execution of the child and parent are not what you expect, so you see output you don't understand. On my Arch linux box (kernel 4.xx), it works fine, but the parent process returns first, leaving ls to overwrite and otherwise garble the command prompt. Do a wait() on the child process to get execution to happen in a specific order. Add a couple of lines of code after the spawn() call:
spawn("ls", arg_list);
printf("return to parent\n");
wait(&child_stat);
printf("Waited on child\n");
return 0;
After the fork() call, the parent process will call wait(), which won't return until a child process (if there is at least one) exits. Since there's only one child process, the output of ls occurs before the command prompt gets written out, and thus you will see what you believe you should see.
I've been experimenting with Overlapped IO feature of Win32 API, namely ReadFileEx and WriteFileEx functions.
Here is a simplest example:
#include <iostream>
#include <string>
#include <Windows.h>
const DWORD blockSize = 512;
char buffer[blockSize];
bool done = false;
OVERLAPPED overlapped;
void Completion(DWORD error, DWORD read, LPOVERLAPPED overlapped) {
}
int _tmain(int argc, _TCHAR* argv[])
{
std::wstring fileName;
std::wcout << "Enter file name: ";
std::getline(std::wcin, fileName);
HANDLE file = CreateFile(
fileName.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (file == INVALID_HANDLE_VALUE) {
std::wcout << "Error while opening file: " << GetLastError() << std::endl;
std::cin.get();
return -1;
}
overlapped.Offset = overlapped.OffsetHigh = 0;
ReadFileEx(file, buffer, blockSize, &overlapped, (LPOVERLAPPED_COMPLETION_ROUTINE) &Completion);
while (!done)
SleepEx(1000, TRUE);
return 0;
}
As you can see, I'm starting overlapped reading with ReadFileEx and waiting for it to finish using SleepEx. Although Completion has empty body and the program should hang forever after reading first block, it does something completely different. In fact, it raises AccessViolation with code 0xC0000005 on the first call to SleepEx. This happens on Windows machines with Win 7 and Win Vista I've tried, including fresh 64 bit virtual machine with Windows 7. But, curiously, it does not fail on one Windows 8.1 machine and runs just as expected. This was compiled with Visual Studio 2010, but I don't think it matters.
I can not understand what have I done wrong, so if anyone knows the answer, please help me.
The callback must be of the following form, as stated clearly in the documentation:
VOID CALLBACK FileIOCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
);
Your function has the wrong calling convention. Your cast does not change that. It is simply a way for you to stop the compiler rejecting your ill-formed program. Don't lie to the compiler. Correct the function declaration by adding the CALLBACK calling convention.
My C++ 2011 main() program for DiGSE is:
int main(int argc, char* argv[]) {
. . .
return EXIT_SUCCESS;
} // this } DOES match the opening { above
It compiles and executes correctly. A print statement immediately before the return outputs normally. However, a Windows 7.1 notification pops up saying "DiGSE.exe has stopped working." It then graciously offers to search the web for a solution.
I tried replacing the return with return 0; exit(0); and nothing so execution falls out the bottom (which, as I understand, is acceptable). However, in all cases I still get the pop-up.
What do I do to get the main() to exit gracefully?
DiGSE is just the name of the Windows 7 executable compiled on MinGW 4.9.2. The "full" program is already stripped down:
int main(int argc, char* argv[]) {
try {
DiGSE::log_init(DiGSE::log_dest_T::console_dest, "dig.log", true,
DiGSE::log_lvl_T::trace_lvl);
}//try
catch (const std::exception& ex) {
std::cerr << FMSG("\n"
"Executing '%1%' raised this exception:\n"
" %2%", % DiGSE::Partition::productName()
% ex.what())
<< std::endl;
return EXIT_FAILURE;
}//exception
catch (...) {
std::cerr << FMSG("\n"
"Executing '%1%' instance raised an unknown exception.",
% DiGSE::Partition::productName())
<< std::endl;
return EXIT_FAILURE;
}//exception
L_INFO(FMSG("'%1% v%2%' terminated normally.",
% DiGSE::Partition::productName()
% DiGSE::Partition::productVersion()))
return EXIT_SUCCESS;
}//main()
The L_INFO() is a logging call, which outputs as it should. The log_init() at the top initializes the log. Commenting out log_init() and L_INFO() has the same result as originally reported.
Program received signal SIGSEGV, Segmentation fault.
0x000000006fc8da9d in libstdc++-6!_ZNSo6sentryC1ERSo ()
from D:\Program Files\mingw-w64\x86_64-4.9.2-posix-seh-rt_v3-rev0\mingw64\bin
\libstdc++-6.dll
This is what gdb returns while mail() is exiting. It does this even with the log_init() and L_LNFO() commented out. So the problem is probably in one of globals of something it's linked to.
It is completely possible for a program to crash after the end of main -- the program isn't over yet. The following items execute after main() returns:
Registered at_exit handlers
Destructors for main()'s own automatic variables, and all variables with static storage duration (globals and function-static) (C++ only)
DllMain(PROCESS_DETACH) code in all dynamic libraries you are using (Windows only)
In addition to that, various events can occur outside your program and cause failures which you might mistake for a failure of your program (especially if your program forks or spawns copies of itself):
SIGCHLD is raised (on *nix). Process handles become signaled and cause wait functions to return (on Windows)
All open handles (file descriptors) get abandoned, and the close handler in the driver is invoked
The other end of connections (pipes, sockets) shift into a disconnected state (reads return 0, writes fail, on *nix SIGHUP may be raised)
I suggest attaching a debugger, set a breakpoint at the end of main, and then single-step through the cleanup code to find out where the failure is occurring. Divide and conquer may also be helpful (cut out some global variables, or all usage of a particular DLL).
Is fprintf thread safe on OS X? If so, where is this documented?
The POSIX threads specification (AKA Pthreads), which OS X conforms to, requires that stdio functions are thread safe. It also provides the flockfile and funlockfile functions to ensure that other threads can't interleave I/O on a FILE * whilst it is locked.
See http://pubs.opengroup.org/onlinepubs/007908799/xsh/threads.html, specifically under the section titled "Thread-safety".
This was a good question, although similar questions have been asked here many times. I was interested in the OSX aspect because I trying to get up to speed on that system myself. (maybe you should add the OSX tag)
I THINK fprintf() is thread safe on OSX. My first reason for this is that the Darwin people were going in that direction as evidenced by their choice to drop the old-school global 'errno' in favor of the function errno(). For documentation, just follow '/usr/include/errno.h'. Without that, none of the libc stuff would be thread safe. Yet the use of the errno() function doesn't prove anything about fprintf(). It's just a start. I'm sure everyone knows of at least one situation where Apple didn't carry through with a good idea.
Another reason I believe in the 'thread-safety' of fprintf() is the source code, which is supposed to be 'the real thing', at least until 10.6 when Apple closed (part / all) of OSX. Scan that code for "MT-Safe" and you will see a CLAIM that the non-locale version of 'vfprintf()' is thread safe. Again, that doesn't prove anything. Yet it is a form of documentation, which you wanted.
My final reason to believe fprintf() is thread-safe was a test case. This doesn't prove much of anything either. Maybe it proves the buffer space is thread safe. OK, it was an excuse to write a little program for fun. Actually, I didn't write it. I found a skeleton online, and modified it. The "FLUSH_BUFFER" definition allows you to more clearly see what's happening. If that macro isn't defined, you get 'sort-of' buffer test (same text without some line-terminators). I couldn't figure out a way to arrange a more meaningful collision of the threads.
I'll guess you might be writng to multiple files. Writing to a single file is probably a better test. The attached program isn't a definitive test. Although it could be extended, I'm not sure any program could really be definitive. Bottom line: maybe you should just MUTEX your calls to fprintf().
// artificial test for thread safety of fprintf()
// define FLUSH_BUFFER to get a good picture of what's happening, un-def for a buffer test
// the 'pretty print' (FLUSH_BUFFER) output relies on a mono-spaced font
// a writeable file name on the command line will send output to that file
//
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define FLUSH_BUFFER
#define NTHREAD 5
#define ITERATIONS 3
const char DOTS[] = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
FILE *outFile;
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
for (int i=1; i<=ITERATIONS; i++) {
long delay = (NTHREAD-tid) * 100000 + (ITERATIONS-i+1) * 10000;
#ifdef FLUSH_BUFFER
fprintf(outFile, "%*sStart thread %d iteration %d\n", (tid+1)*4, " ", tid, i);
usleep(delay);
fprintf(outFile, "%*sFinish thread %d iteration %d %*.*sw/delay %d\n",
(tid+1)*4, " ", tid, i, (NTHREAD-tid+1)*4, (NTHREAD-tid+1)*4, DOTS, delay);
#else
fprintf(outFile, "Start thread %d iteration %d ", tid, i);
usleep(delay);
fprintf(outFile, "Finish thread %d iteration %d w/delay %d\n", tid, i, delay);
#endif
}
pthread_exit(NULL);
}
int main (int argc, char *argv[]) {
pthread_t threads[NTHREAD];
char errStr[100];
int rc;
long t;
if(argc > 1) {
if(! (outFile = fopen(argv[1], "w"))) {
perror(argv[1]);
exit(1);
}
} else
outFile = stdout;
for(t=0; t<NTHREAD; t++) {
fprintf(outFile, "In main: creating thread %ld\n", t);
if(rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t)) {
sprintf(errStr, "ERROR; pthread_create() returned %d", rc);
perror(errStr);
exit(2);
}
}
pthread_exit(NULL);
}