So I was making an application using C++ Console, with multi threading as below, then I got an error 0x0000005.
The first time it run it was working as usual. Can anyone help me with this problem?
I am using Code::Blocks IDE with Borland C++ 5.5, and I am planning to make this into Borland C++ 5.02
#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <iostream.h>
#include <conio.h>
void linesmov(int mseconds, int y);
void linesmov(int mseconds, int y)
{
int i=0;
while (true)
{
i=i+1;
// Or system("cls"); If you may...
gotoxy(i,y);
cout << "____||____||____";
gotoxy(i-1,y);
cout << " ";
Sleep(mseconds);
if (i>115)
{
i=0;
for(int o = 0; o < 100; o++)
{
gotoxy(0,y);
cout << " ";
}
}
}
}
DWORD WINAPI mythread1(LPVOID lpParameter)
{
printf("Thread inside %d \n", GetCurrentThreadId());
linesmov(5,10);
return 0;
}
DWORD WINAPI mythread2(LPVOID lpParameter)
{
printf("Thread inside %d \n", GetCurrentThreadId());
linesmov(30,15);
return 0;
}
int main(int argc, char* argv[])
{
HANDLE myhandle1;
DWORD mythreadid1;
HANDLE myhandle2;
DWORD mythreadid2;
myhandle1 = CreateThread(0,0,mythread1,0,0,&mythreadid1);
myhandle2 = CreateThread(0,0,mythread2,0,0,&mythreadid2);
printf("Thread after %d \n", mythreadid1);
getchar();
return 0;
}
All of these solutions in comments including mine are definitely not the way how it should be done. The main problem is lack of synchronization between threads and lack of processing their termination. Also, every function should be checked for thread-safe compatibility or should be wrapped to match it.
Considering std::cout since c++11 we have some data race guarantees:
Concurrent access to a synchronized (§27.5.3.4) standard iostream
object’s formatted and unformatted input (§27.7.2.1) and output
(§27.7.3.1) functions or a standard C stream by multiple threads shall
not result in a data race (§1.10). [ Note: Users must still
synchronize concurrent use of these objects and streams by multiple
threads if they wish to avoid interleaved characters. — end note ]
So lask of synchronization primitives is oblivious according to this note.
Considering processing of thread termination.
HANDLE threadH = CreateThread(...);
...
TerminateThread(threadH, 0); // Terminates a thread.
WaitForSingleObject(threadH, INFINITE); // Waits until the specified object is in the signaled state or the time-out interval elapses.
CloseHandle(threadH); // Closes an open object handle.
TerminateThread(), but be aware of this solution, because ..
WaitForSingleObject()
And this is only first steps to thread-safe way.
I would like to recommend C++ Concurrency in Action: Practical Multithreading by Anthony Williams for further reading.
Rude solution for synchronized output
#include <Windows.h>
#include <iostream>
#include <mutex>
std::mutex _mtx; // global mutex
bool online = true; // or condition_variable
void gotoxy(int x, int y)
{
COORD c = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void linesmov(int mseconds, int y) {
int i = 0;
while (online) {
i = i + 1;
// Or system("cls"); If you may...
_mtx.lock(); // <- sync here
gotoxy(i, y);
std::cout << "____||____||____"; gotoxy(i - 1, y);
std::cout << " ";
_mtx.unlock();
Sleep(mseconds);
if (i > 75)
{
i = 0;
for (int o = 0; o < 60; o++)
{
_mtx.lock(); // <- sync here
gotoxy(0, y);
std::cout << " ";
_mtx.unlock();
}
}
}
}
DWORD WINAPI mythread1(LPVOID lpParameter)
{
std::cout << "Thread 1" << GetCurrentThreadId() << std::endl;
linesmov(5, 10);
return 0;
}
DWORD WINAPI mythread2(LPVOID lpParameter)
{
std::cout << "Thread 2" << GetCurrentThreadId() << std::endl;
linesmov(30, 15);
return 0;
}
int main(int argc, char* argv[])
{
DWORD mythreadid1;
DWORD mythreadid2;
HANDLE myhandle1 = CreateThread(0, 0, mythread1, 0, 0, &mythreadid1);
HANDLE myhandle2 = CreateThread(0, 0, mythread2, 0, 0, &mythreadid2);
std::cout << "Base thread: " << GetCurrentThreadId() << std::endl;
getchar();
online = false;
WaitForSingleObject(myhandle1, INFINITE);
WaitForSingleObject(myhandle2, INFINITE);
CloseHandle(myhandle1);
CloseHandle(myhandle2);
return 0;
}
a) Both gotoxy not outputting via std::cout are not thread safe /synchronized. You need process-wide mutex to synchronize that
b) exception is likely due to fact that you do not use WaitForMultipleObjects in main to wait for threads to finish. Depending on hardware and optimization main may exit before threads finish their work.
Related
In Win32 C++, How to WaitForSingleObject and Detect Ctrl-C at the same time?
I tried the following console application by compiling it in the Code::Blocks C++ compiler for windows.
Then, I tried pressing Control-C many times while running... it basically doesn't call the control-c handler while the main thread is in "WaitForSingleObject".
Is there a way to fix this?
Eventually, I want my Control-C handler to kill the secondary thread using TerminateThread and return control to mainthread breaking WaitForSingleObject... But, because of the wait the second thread is written i can't change any of the code...
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <atomic>
using namespace std;
BOOL WINAPI fun1(DWORD id);
DWORD WINAPI fun2(void*);
atomic<DWORD> threadid {0};
int main()
{
DWORD threadid1;
cout << "Hello world!" << endl;
SetConsoleCtrlHandler(fun1, TRUE);
HANDLE H1 = CreateThread(NULL, 0, fun2, 0, 0, &threadid1);
threadid = threadid1;
WaitForSingleObject(H1, INFINITE);
return 0;
}
BOOL WINAPI fun1(DWORD id)
{
Beep(750, 300);
printf("CtrlHandler:(%ld)\n", id);
if (threadid != 0) {
HANDLE H2 = OpenThread(THREAD_TERMINATE, FALSE, threadid);
if (H2) {
//TerminateThread(H2, 0);
//threadid = 0;
CloseHandle(H2);
}
}
return TRUE;
}
DWORD WINAPI fun2(void*)
{
// This thread will eventually do some work...
// and I don't want to rewrite this code...
// to check for a flag from another thread...
int count = 0;
while(1) {
printf("count: %d\n", count);
Sleep(1000);
}
return 0;
}
A SetConsoleCtrlHandler() handler gets run by the OS in its own thread. This is stated as much in the documentation:
https://learn.microsoft.com/en-us/windows/console/handlerroutine
An application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function.
You need to have that signal thread notify your worker thread to terminate itself, you can't (safely) just terminate the thread directly (ie, DO NOT use TerminateThread()).
Try this:
#include <windows.h>
#include <cstdio>
#include <iostream>
#include <atomic>
using namespace std;
BOOL WINAPI fun1(DWORD);
DWORD WINAPI fun2(void*);
atomic<bool> exitThread {false};
int main()
{
cout << "Hello world!" << endl;
SetConsoleCtrlHandler(fun1, TRUE);
HANDLE H1 = CreateThread(NULL, 0, fun2, 0, 0, NULL);
if (H1)
{
WaitForSingleObject(H1, INFINITE);
CloseHandle(H1);
}
return 0;
}
BOOL WINAPI fun1(DWORD id)
{
Beep(750, 300);
printf("CtrlHandler:(%lu)\n", id);
exitThread = true;
return TRUE;
}
DWORD WINAPI fun2(void*)
{
// This thread will eventually do some work...
int count = 0;
while (!static_cast<bool>(exitThread)) {
printf("count: %d\n", count++);
Sleep(1000);
}
return 0;
}
However, do note that creating a thread just to wait on it is a waste of a thread. You may as well just do your work in main() directly instead, eg:
#include <windows.h>
#include <cstdio>
#include <iostream>
#include <atomic>
using namespace std;
BOOL WINAPI fun1(DWORD);
atomic<bool> exitApp {false};
int main()
{
cout << "Hello world!" << endl;
SetConsoleCtrlHandler(fun1, TRUE);
// This will eventually do some work...
int count = 0;
while (!static_cast<bool>(exitApp)) {
printf("count: %d\n", count++);
Sleep(1000);
}
return 0;
}
BOOL WINAPI fun1(DWORD id)
{
Beep(750, 300);
printf("CtrlHandler:(%lu)\n", id);
exitApp = true;
return TRUE;
}
I cleaned up your code slightly and it seems like the Ctrl+C handler is running when expected (even though it doesn't do anything particularly useful). When I type Ctrl+C, I see that fun1 can run multiple times while the main thread is running WaitForSingleObject.
Your original code for fun1 was beeping before printing, and it wasn't flushing the stdout buffer, so maybe you thought the code wasn't actually running or that it was getting delayed.
Note that I am just answering questions you asked about detecting Ctrl+C while waiting for an object; I'm not attempting to help you do anything useful in your Ctrl+C handler.
Here is the cleaned-up version of your code that I used for testing:
#include <windows.h>
#include <stdio.h>
#include <atomic>
std::atomic<DWORD> threadid {0};
BOOL WINAPI fun1(DWORD id) {
printf("fun1: %ld\n", id);
fflush(stdout);
Beep(750, 100);
// This doesn't do anything useful; can be removed.
if (threadid != 0) {
HANDLE H2 = OpenThread(THREAD_TERMINATE, FALSE, threadid);
if (H2) { CloseHandle(H2); }
}
return 1;
}
DWORD WINAPI fun2(void *) {
unsigned int count = 0;
while(1) {
count++;
printf("count: %d\n", count);
fflush(stdout);
Sleep(4000);
}
return 0;
}
int main() {
printf("Hello world!\n");
fflush(stdout);
SetConsoleCtrlHandler(fun1, TRUE);
DWORD threadid1;
HANDLE H1 = CreateThread(NULL, 0, fun2, 0, 0, &threadid1);
threadid = threadid1;
printf("Waiting for single oblect.\n");
fflush(stdout);
WaitForSingleObject(H1, INFINITE);
printf("Done waiting for single oblect.\n");
fflush(stdout);
return 0;
}
Example output:
Hello world!
Waiting for single oblect.
count: 1
count: 2
fun1: 0
fun1: 0
fun1: 0
fun1: 0
fun1: 0
fun1: 0
fun1: 0
fun1: 0
fun1: 0
count: 3
count: 4
I compiled the code in MSYS2, targeting 64-bit Windows, with this command:
g++ -std=gnu++20 -Wall -Wextra test.cpp
I plan on rewriting this to assembly so I can't use c or c++ standard library. The code below runs perfectly. However I want a thread instead of a second process. If you uncomment /*CLONE_THREAD|*/ on line 25 waitpid will return -1. I would like to have a blocking function that will resume when my thread is complete. I couldn't figure out by looking at the man pages what it expects me to do
#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
int globalValue=0;
static int childFunc(void*arg)
{
printf("Global value is %d\n", globalValue);
globalValue += *(int*)&arg;
return 31;
}
int main(int argc, char *argv[])
{
auto stack_size = 1024 * 1024;
auto stack = (char*)mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (stack == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); }
globalValue = 5;
auto pid = clone(childFunc, stack + stack_size, /*CLONE_THREAD|*/CLONE_VM|CLONE_SIGHAND|SIGCHLD, (void*)7);
sleep(1); //So main and child printf don't collide
if (pid == -1) { perror("clone"); exit(EXIT_FAILURE); }
printf("clone() returned %d\n", pid);
int status;
int waitVal = waitpid(-1, &status, __WALL);
printf("Expecting 12 got %d. Expecting 31 got %d. ID=%d\n", globalValue, WEXITSTATUS(status), waitVal);
return 0;
}
If you want to call functions asynchronously with threads I recommend using std::async. Example here :
#include <iostream>
#include <future>
#include <mutex>
#include <condition_variable>
int globalValue = 0; // could also have been std::atomic<int> but I choose a mutex (to also serialize output to std::cout)
std::mutex mtx; // to protect access to data in multithreaded applications you can use mutexes
int childFunc(const int value)
{
std::unique_lock<std::mutex> lock(mtx);
globalValue = value;
std::cout << "Global value set to " << globalValue << "\n";
return 31;
}
int getValue()
{
std::unique_lock<std::mutex> lock(mtx);
return globalValue;
}
int main(int argc, char* argv[])
{
// shared memory stuff is not needed for threads
// launch childFunc asynchronously
// using a lambda function : https://en.cppreference.com/w/cpp/language/lambda
// to call a function asynchronously : https://en.cppreference.com/w/cpp/thread/async
// note I didn't ues the C++ thread class, it can launch things asynchronously
// however async is both a better abstraction and you can return values (and exceptions)
// to the calling thread if you need to (which you do in this case)
std::future<int> future = std::async(std::launch::async, []
{
return childFunc(12);
});
// wait until asynchronous function call is complete
// and get its return value;
int value_from_async = future.get();
std::cout << "Expected global value 12, value = " << getValue() << "\n";
std::cout << "Expected return value from asynchronous process is 31, value = " << value_from_async << "\n";
return 0;
}
I wrote the following structure to implement a simple single producer / multi consumer synchronization. I'm using two integers available_index and consumed_index, access to consumed_index is protected by the condition variable cv. Here's the code:
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <thread>
struct ParserSync {
std::mutex worker_lock;
std::condition_variable cv;
int consumed_index = -1;
int available_index = -1;
bool exit_flag = false;
int consume_index() {
int ret = -1;
// get worker_lock
std::unique_lock<std::mutex> w_lock(worker_lock);
// wait for exit_flag or new available index
cv.wait(w_lock, [this] { return exit_flag || available_index > consumed_index; });
if (available_index > consumed_index) {
consumed_index++;
ret = consumed_index;
}
// Unlock mutex and notify another thread
w_lock.unlock();
cv.notify_one();
return ret;
}
void publish_index() {
available_index++;
std::cout << "before" << std::endl;
cv.notify_one();
std::cout << "after" << std::endl;
}
void set_exit() {
exit_flag = true;
cv.notify_all();
}
};
I tested my implementation using the following code (just a simple example to show the problem):
void producer(ParserSync &ps){
for (int i=0;i<5000;i++){
ps.publish_index();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
ps.set_exit();
std::cout << "Producer finished!" << std::endl;
}
void consumer(ParserSync &ps){
while (true){
int idx = ps.consume_index();
if (idx == -1)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(4));
}
std::cout << "Consumer finished!" << std::endl;
}
int main() {
ParserSync ps{};
const int num_consumers = 4;
std::vector<std::thread> consumer_threads(num_consumers);
// start consumers
for (int i = 0; i < num_consumers; ++i) {
consumer_threads[i] = std::thread{consumer, std::ref(ps)};
}
// start producer
std::thread producer_thread = std::thread{producer, std::ref(ps)};
for (int i = 0; i < num_consumers; ++i) {
consumer_threads[i].join();
}
producer_thread.join();
std::cout << "Program finished" << std::endl;
return 0;
}
I would expect that producer thread produces 5000 indices and exits afterwards, but unfortunately, it gets stuck at some random iteration. I used print statements to find the code line that blocks and tracked it down to cv.notify_one();. This is the (shortened) console output:
...
before
after
before
after
before
Does anyone know why the call to cv.notify_one(); blocks?
I'm using MinGW (x86_64-6.2.0-posix-seh-rt_v5-rev1) on Windows 10.
Thanks in advance!
EDIT:
When compiling the exact same code with Visual Studio, the program works as expected and doesn't lock itself up. Unfortunately, I need to use MinGW for other reasons.
According to https://msdn.microsoft.com/en-us/library/hh567368.aspx
Magic statics (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm)
are supported on VS2015
However testing the following code in debug x64 Vs2015 Update 3
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <tchar.h>
#define MAX_THREADS 5
class Sleeper
{
public:
Sleeper()
{
std::cout << "Sleeper \n";
Sleep(100000);
}
};
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
std::cout << "Sleeper Start" << (int)lpParam << "\n";
static Sleeper s;
std::cout << "Sleeper Done" << (int)lpParam << "\n";
return 0;
}
int main(int, char**)
{
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
// Create MAX_THREADS worker threads.
for (int i = 0; i<MAX_THREADS; i++)
{
// Create the thread to begin execution on its own.
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
(LPVOID)i, // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
// Check the return value for success.
// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.
if (hThreadArray[i] == NULL)
{
ExitProcess(3);
}
} // End of main thread creation loop.
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
// Close all thread handles and free memory allocations.
for (int i = 0; i<MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
}
return 0;
}
gives output
Sleeper Start0 Sleeper Sleeper Start2 Sleeper Start3 Sleeper Start1
Sleeper Start4
Which indicates that initializing static variable s is actually not thread safe.
Yes it does. The test was wrong. Removing the word sleeper from MyThreadFunction shows the expected output
Start1 Sleeper Start4 Start3 Start0 Start2 Done3 Done1 Done0 Done2
Done4
I'm creating 9 threads using something like this (all threads will process infinity loop)
void printStr();
thread func_thread(printStr);
void printStr() {
while (true) {
cout << "1\n";
this_thread::sleep_for(chrono::seconds(1));
}
}
I also create 10th thread to control them. How would I stop or kill any of this 9 threads from my 10th? Or suggest another mechanism please.
You can use, for example, atomic boolean:
#include <thread>
#include <iostream>
#include <vector>
#include <atomic>
using namespace std;
std::atomic<bool> run(true);
void foo()
{
while(run.load(memory_order_relaxed))
{
cout << "foo" << endl;
this_thread::sleep_for(chrono::seconds(1));
}
}
int main()
{
vector<thread> v;
for(int i = 0; i < 9; ++i)
v.push_back(std::thread(foo));
run.store(false, memory_order_relaxed);
for(auto& th : v)
th.join();
return 0;
}
EDIT (in response of your comment): you can also use a mutual variable, protected by a mutex.
#include <thread>
#include <iostream>
#include <vector>
#include <mutex>
using namespace std;
void foo(mutex& m, bool& b)
{
while(1)
{
cout << "foo" << endl;
this_thread::sleep_for(chrono::seconds(1));
lock_guard<mutex> l(m);
if(!b)
break;
}
}
void bar(mutex& m, bool& b)
{
lock_guard<mutex> l(m);
b = false;
}
int main()
{
vector<thread> v;
bool b = true;
mutex m;
for(int i = 0; i < 9; ++i)
v.push_back(thread(foo, ref(m), ref(b)));
v.push_back(thread(bar, ref(m), ref(b)));
for(auto& th : v)
th.join();
return 0;
}
It is never appropriate to kill a thread directly, you should instead send a signal to the thread to tell it to stop by itself. This will allow it to clean up and finish properly.
The mechanism you use is up to you and depends on the situation. It can be an event or a state checked periodically from within the thread.
std::thread objects are non - interruptible. You will have to use another thread library like boost or pthreads to accomplish your task. Please do note that killing threads is dangerous operation.
To illustrate how to approach this problem in pthread using cond_wait and cond_signal,In the main section you could create another thread called monitor thread that will keep waiting on a signal from one of the 9 thread.
pthread_mutex_t monMutex;////mutex
pthread_cond_t condMon;////condition variable
Creating threads:
pthread_t *threads = (pthread_t*) malloc (9* sizeof(pthread_t));
for (int t=0; t < 9;t++)
{
argPtr[t].threadId=t;
KillAll=false;
rc = pthread_create(&threads[t], NULL, &(launchInThread), (void *)&argPtr[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
creating monitor thread:
monitorThreadarg.threadArray=threads;//pass reference of thread array to monitor thread
monitorThreadarg.count=9;
pthread_t monitor_thread;
rc= pthread_create(&monitor_thread,NULL,&monitorHadle,(void * )(&monitorThreadArg));
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
then wait on 9 threads and monitor thread:
for (s=0; s < 9;s++)
{
pthread_join(threads[s], &status);
}
pthread_cond_signal(&condMon);// if all threads finished successfully then signal monitor thread too
pthread_join(monitor_thread, &status);
cout << "joined with monitor thread"<<endl;
The monitor function would be something like this:
void* monitorHadle(void* threadArray)
{
pthread_t* temp =static_cast<monitorThreadArg*> (threadArray)->threadArray;
int number =static_cast<monitorThreadArg*> (threadArray)->count;
pthread_mutex_lock(&monMutex);
mFlag=1;//check so that monitor threads has initialised
pthread_cond_wait(&condMon,&monMutex);// wait for signal
pthread_mutex_unlock(&monMutex);
void * status;
if (KillAll==true)
{
printf("kill all \n");
for (int i=0;i<number;i++)
{
pthread_cancel(temp[i]);
}
}
}
the function what will be launched over 9 threads should be something like this:
void launchInThread( void *data)
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while(1)
{
try
{
throw("exception whenever your criteria is met");
}
catch (string x)
{
cout << "exception form !! "<< pthread_self() <<endl;
KillAll=true;
while(!mFlag);//wait till monitor thread has initialised
pthread_mutex_lock(&monMutex);
pthread_cond_signal(&condMon);//signail monitor thread
pthread_mutex_unlock(&monMutex);
pthread_exit((void*) 0);
}
}
}
Please note that if you dont't put :
thread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
after launching your thread then your threads wouldn't terminate on thread_cancel call.
It is necessary that you clean up up all the data before you cancel a thread.