PThread Crashes Within Class in C++ - c++

So I am pretty new to threading in general and have been experimenting with pthreads for the past couple of weeks. I have created a class that has a threaded function within itself. It works fine, until I tried to set a class property (an integer) to a value.
.h file:
#ifndef TESTCLASS_H
#define TESTCLASS_H
#include <iostream>
#include <windows.h>
using namespace std;
class testClass
{
public:
testClass();
HANDLE h;
static DWORD WINAPI mythread(LPVOID param);
int mytestint;
void printstuffs();
void startThread();
};
#endif // TESTCLASS_H
.cpp file
#include "testClass.h"
testClass::testClass()
{
cout << "Created class" << endl;
}
DWORD WINAPI testClass::mythread(LPVOID param)
{
cout << "In thread" << endl;
testClass* This = (testClass*)param;
cout << "Calling class function" << endl;
This->printstuffs();
cout << "Thread is done" << endl;
return NULL;
}
void testClass::printstuffs()
{
cout << "In class function " << endl;
mytestint = 42; // <- crashes here
cout << "Test Int = " << mytestint << endl;
}
void testClass::startThread()
{
h = CreateThread(NULL, 0, mythread, (LPVOID)0, 0, NULL);
cout << "Thread started" << endl;
}
So why does it crash when I call mytestint = 42; ?

You're calling mythread with a null pointer. When you cast that to This, you end up calling a function on a null object. When you do mytestint = 42, the computer sees it like this->mytestint = 42, and since this is NULL, you dereference a null pointer, and the program segfaults. You need to do something like the following:
h = CreateThread(NULL, 0, mythread, (LPVOID)this, 0, NULL);
If possible, I would also suggest migrating over to standard C++ threads introduced in C++11. Since it looks like you're just learning multithreading it would be useful to learn the standard facilities (which are included with the latest versions of MSVC and GCC) vice vendor-specific APIs.

The way you are implementing the thread call back is not correct. And are you sure that its crashing at the integer assignment, I assume it must be crashing in te first line of your Thread Call back.
You are not passing a reference to "this" in the CreateThread function call.

Related

Parsing Pointers & Using them between classes [C++]

So I'm fairly new to C++ and I've only started to code into it a few weeks or so. I've been facing a problem that I could not manage to fix. Every time I learned a new programming language, I give myself the challenge to make a little program (not too complex) which groups everything I've learned about that language (functions, classes, arrays, pointers and so on) so I can get a good understand of how actually coding in that language is.
So I decided to make my first C++ program called Chek to check the current MBPS (connection speed) every hour, minutes, or second that the user can input. Like all of my programs, I use a structure that I always use that I discovered while coding in Java (Since I know Java fluidly). Which looks like this:
I've also added a comment of where my issue is in the whole in Lib/Arguments.cpp.
Let's say I was to code Chek in Java. I would do my structure like:
Chek or Main class
|- Core
|- Core (The class that handles initiating each core's libraries)
|- Arguments (For parsing, checking and understand arguments)
|- Broadcast (To print to screen and so on)
|- Network (For network interaction)
|- Logs (To save to file logs)
Then the rest ...
Each Core's lib is handled by the Core, like... To call the Broadcast methods, I would do:
Main().getCore().getBroadcast().BroadcastMsg("Hello!");
So I can access all libraries, methods, and variables without creating deadlocks or any infinite importing loops.
My problem is I'm trying to do this in C++ but it's not working! I've tried a lot of stuff, changing pointers to Object and so on but it doesn't work so I need help!
Here's my code (I'm also using Visual Studio):
Chek.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include <iostream>
int main(int argc, char *argv[])
{
Core* Ptr = new Core;
Main OBJ; Main* Ptr2; Ptr2 = &OBJ;
std::cout << "Generated PTR's!" << std::endl;
std::cout << "Core PTR -> " << Ptr << std::endl;
std::cout << "Main PTR -> " << Ptr2 << std::endl << std::endl;
Ptr2->SetCrPtr(Ptr);
Ptr2->loadChek(argv);
}
Main/Main.h:
#pragma once
#ifndef __MAIN_H
#define __MAIN_H
class Core;
class Main
{
public:
Main();
private:
Core* CrPtr;
public:
void loadChek(char *arguments[]);
void SetCrPtr(Core* Ptr);
Core* getCrPtr();
};
#endif
Main/Main.cpp:
#include "pch.h"
#include "Main.h"
#include "Core.h"
#include "Arguments.h"
#include "Broadcast.h"
#include <iostream>
using namespace std;
Main::Main() : CrPtr() {};
void Main::SetCrPtr(Core* Ptr)
{
std::cout << "[Main] Setting CrPtr to " << Ptr << std::endl;
this->CrPtr = Ptr;
}
Core* Main::getCrPtr()
{
return this->CrPtr;
}
void Main::loadChek(char *arguments[])
{
char *allArguments[sizeof(arguments)];
this->CrPtr->SetMnPtr(this);
this->CrPtr->setArguments();
this->CrPtr->setBroadcast();
this->CrPtr->getBroadcast()->Log(1, "Loading arguments ...\n");
this->CrPtr->getArguments()->parseArguments(arguments, allArguments);
}
Core/Core.h:
#pragma once
#ifndef __CLASS_H
#define __CLASS_H
#include "Arguments.h"
#include "Broadcast.h"
class Main;
class Core
{
public:
Core();
private:
Main* MnPtr;
Arguments* ArgPtr;
Broadcast* BrdPtr;
public:
Arguments* getArguments();
void setArguments();
Broadcast* getBroadcast();
void setBroadcast();
void SetMnPtr(Main* Ptr);
};
#endif
Core/Core.cpp:
#include "pch.h"
#include "Core.h"
#include "Main.h"
Core::Core() : MnPtr() {}
void Core::SetMnPtr(Main* Ptr)
{
std::cout << "[Core] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Core::setArguments()
{
this->ArgPtr = new Arguments;
std::cout << "[Core] Setting Argument's MnPtr to " << this->MnPtr << std::endl;
this->ArgPtr->SetMnPtr(this->MnPtr);
}
void Core::setBroadcast()
{
this->BrdPtr = new Broadcast;
std::cout << "[Core] Setting Broadcast's MnPtr to " << this->MnPtr << std::endl;
this->BrdPtr->SetMnPtr(this->MnPtr);
}
Arguments* Core::getArguments()
{
return ArgPtr;
}
Broadcast* Core::getBroadcast()
{
return BrdPtr;
}
Lib/Arguments.h:
#pragma once
class Main;
class Arguments
{
public:
Arguments();
private:
Main* MnPtr;
public:
void parseArguments(char *arguments[], char *argumentsElements[]);
void SetMnPtr(Main* Ptr);
Main* GetMnPtr();
};
Lib/Arguments.cpp:
#include "pch.h"
#include "Arguments.h"
#include <iostream>
Arguments::Arguments() : MnPtr() {}
void Arguments::SetMnPtr(Main* Ptr)
{
std::cout << "[Arguments] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
Main* Arguments::GetMnPtr()
{
return this->MnPtr;
}
void Arguments::parseArguments(char *arguments[], char *argumentsElements[])
{
try {
if (sizeof(arguments) == 1 || sizeof(arguments) > 4) throw 1;
}
catch (int errorCode) {
if (errorCode == 1) std::cout << "Wrong usage!\n\nUsage: chek.exe <timeout-in-miliseconds> <log-file-path>\nExample: chek.exe 10000 saturday_log_file.txt\n";
}
std::cout << "Size -> " << sizeof(arguments) << std::endl;
for(int i=0; i<sizeof(arguments); i++)
{
// The error is produced here, for some reason after MnPtr,
// nothing is recognised. Like getCrPtr()... has never been declared?
this->MnPtr->getCrPtr()->getBroadcast()->(1, "Works!");
}
}
Lib/Broadcast.h:
#pragma once
#include <iostream>
#include "Main.h"
class Broadcast
{
public:
Broadcast();
private:
Main* MnPtr;
public:
void Log(unsigned int statusLevel, std::string message);
void SetMnPtr(Main* Ptr);
};
Lib/Broadcast.cpp:
#include "pch.h"
#include "Broadcast.h"
#include <iostream>
#include <string>
using namespace std;
Broadcast::Broadcast() : MnPtr() {}
void Broadcast::SetMnPtr(Main* Ptr)
{
std::cout << "[Broadcast] Setting MnPtr to " << Ptr << std::endl;
this->MnPtr = Ptr;
}
void Broadcast::Log(unsigned int statusLevel, string message)
{
switch (statusLevel) {
case 1:
cout << "[.] " << message;
break;
case 2:
cout << "[+] " << message;
break;
case 3:
cout << "[!] " << message;
break;
case 4:
cout << "[X] " << message;
break;
}
}
Errors:
I get 3 errors.
Visual Studio Error (When you hover it):
Arguments *const this
Pointers to incomplete class is not allowed.
From the error box (Visual Studio):
Error C2027 use of undefined type 'Main' Chek2 c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp 30
Error (active) E0393 pointer to incomplete class type is not allowed Chek2 C:\Users\xxx\Documents\Programming\C++\VS Workspace\Chek2\Arguments.cpp 30
Compiler Errors:
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp(30): error C2027: use of undefined type 'Main'
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.h(3): note: see declaration of 'Main'
If anyone could help me with this. I would highly appreciate it! I hope it's not too hard of a problem- fairly new to C++ so I don't know exactly what this is compared to Java.
Thanks to #drescherjm for answering in comments. I just needed to add:
#include "Main.h"
#include "Core.h"
Inside Arguments.cpp's includes!

Why is it bad to pass an ID to a thread in the following way?

I am currently trying to learn POSIX threads and made the simple code that you can see below.
I have been told that it is bad to pass an ID to a thread as you can see I did in this code snippet:
int ID0= 0;
int ID1 = 1;
pthread_create(&thread_zero, NULL, thread_function, (void*)&ID0);
pthread_create(&thread_one, NULL, thread_function, (void*)&ID1);
Why is that?
Also, would it be better to use pthread_self?
The full code:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
void *thread_function(void *arg)
{
for(int i =0; i<=10;i++)
{
std::cout << "Hello # " << i<< " From thread : " <<*((int*)arg) << std::endl;
sleep(1);
}
std::cout <<"Thread "<<*((int*)arg)<< " terminates" << std::endl;
pthread_exit(NULL);
}
int main(){
pthread_t thread_zero;
pthread_t thread_one;
int ID0= 0;
int ID1 = 1;
pthread_create(&thread_zero, NULL, thread_function, (void*)&ID0);
pthread_create(&thread_one, NULL, thread_function, (void*)&ID1);
std::cout << "main: Creating threads" << std::endl;
std::cout << "main: Wating for threads to finish" << std::endl;
pthread_join(thread_zero, NULL);
pthread_join(thread_one, NULL);
std::cout<<"Main: Exiting"<<std::endl;
return 0;
}
Why is that?
There is nothing wrong with your code, so long as you ensure that the ID0 and ID1 do not go out of scope before you join your threads, and that either thread does not modify ID0 and ID1 without proper synchronization.
In general, when passing an entity into thread that is not larger than (void*), it is safer to pass it by value, like so:
pthread_create(&tid, NULL, fn, (void*)ID0);
When done that way, ID0 can go out of scope with no danger that the new thread will access dangling stack, and no danger of a data race (which is undefined behavior).

Semaphores not working on threads

I am trying to understand how semaphores work in C++ but I am having some troubles.
Here is my code:
#include <iostream>
#include <pthread.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
using namespace std;
static sem_t *sem_thread;
static pthread_t thread_id;
void * threadFunc(void *) {
cout << "threadFunc\n";
cout << "threadFunc\n";
cout << "threadFunc\n";
cout << "threadFunc\n";
cout << "threadFunc\n";
sem_post(sem_thread);
return 0;
}
int main()
{
// Init semaphores
sem_thread = sem_open("./semaphores/sem_thread", O_TRUNC, 0777, 0);
// Init thread
int rc = pthread_create(&thread_id, NULL, threadFunc, NULL);
if (rc != 0)
{
cerr << "Pthread couldn't be created. rc=" << rc << endl;
abort();
}
sem_wait(sem_thread);
cout << "Main thread\n";
cout << "Main thread\n";
cout << "Main thread\n";
cout << "Main thread\n";
cout << "Main thread\n";
sem_close(sem_thread);
sem_unlink("./semaphores/sem_thread");
return 0;
}
So I expect the program to print threadFunc first and then Main thread. However, this is what I get:
Main thread
tMhariena dtFhurneca
dt
hMraeiand Ftuhnrce
atdh
rMeaaidnF utnhcr
etahdr
eMaadiFnu ntch
rteharde
adFunc
Any idea of what's happening?
You're not creating the semaphore, nor checking whether it was created.
There are two problems with your call to sem_open:
you need O_CREAT, not O_TRUNC, to create it.
the name isn't valid. Named semaphores aren't kept in the filesystem.
Looking at man sem_overview, the naming convention is specified thusly:
A named semaphore is identified by a name of the form /somename;
that is, a null-terminated string of up to NAME_MAX-4 (i.e.,
251) characters consisting of an initial slash, followed by one
or more characters, none of which are slashes.

C++ very simple thread?

What is the simplest way of making a thread in c++? I want to make one that uses an already declared method to run. Something like:
void task1(){
cout << "Thread started";
}
thread t1 = thread(task1());
I guess I want to make a thread that doesn't require downloading any libraries and that my compiler will most likely be able to compile. And a big question I want answered is, what is c++11? Is it a whole different language, or a bundle of libraries?
C++11 has thread library. A very simple example is:
#include <iostream>
#include <thread>
void task1()
{
std::cout<<"Thread started\n";
}
int main()
{
std::thread t1(task1);
t.join();
}
See http://en.cppreference.com/w/cpp/thread/thread
If you can't use C++11, it depends upon what you are programming for. The following "simple as possible" threading example is written in unmanaged Win32 code, using the CreateThread function:
#include <Windows.h>
#include <tchar.h>
#include <iostream>
using namespace std;
DWORD WINAPI ThreadFunction(LPVOID lpParam) {
WORD numSeconds = 0;
for (;;) {
Sleep(1000);
cout << numSeconds++ << " seconds elapsed in child thread!" << endl;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[]) {
HANDLE hThread;
DWORD threadID;
WORD numSeconds = 0;
cout << "Hello world" << endl;
hThread = CreateThread(NULL, 0, ThreadFunction, NULL, 0, &threadID);
Sleep(500);
for (;;) {
cout << numSeconds++ << " seconds elapsed in main thread!" << endl;
Sleep(1000);
}
return 0;
}
If you use this approach, remember that the function pointer passed to CreateThread must have the signature:
DWORD ThreadFuncion(LPVOID lpParameter);
You can find the description of that signature on MSDN.
C++ standard gets revised often every few years. Some cool things get added and old things are kept for backward compatibility. Here is some history.
Boost has a very good influence in driving the C++ standard.

Synchronization in Pthread C++

I've read about synchronized thread in Posix threads tutorial. They say that function pthread_join is used for waiting thread until it stops. But why doesn't this idea work in that case?
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int a[5];
void* thread(void *params)
{
cout << "Hello, thread!" << endl;
cout << "How are you, thread? " << endl;
cout << "I'm glad to see you, thread! " << endl;
}
void* thread2(void *params)
{
cout << "Hello, second thread!" << endl;
cout << "How are you, second thread? " << endl;
cout << "I'm glad to see you, second thread! " << endl;
// for (;;);
}
int main()
{
pthread_t pt1, pt2;
int iret = pthread_create(&pt1, NULL, thread, NULL);
int iret2 = pthread_create(&pt2, NULL, thread2, NULL);
cout << "Hello, world!" << endl;
pthread_join(pt1, NULL);
cout << "Hello, middle!" << endl;
pthread_join(pt2, NULL);
cout << "The END" << endl;
return 0;
}
Threads are executed asynchronously, as someone already mentioned in answer to question you linked. Thread execution starts right after you create() it. So, at this point:
int iret = pthread_create(&pt1, NULL, thread, NULL);
thread() is already executing in another thread, possibly on another core (but it doesn't really matter). If you add a for (;;); in your main() right after that, you will still see thread message being printed to console.
You also misunderstood what join() does. It waits for thread termination; as your threads don't do any real work, they will (most probably) reach their ends and terminate way before you call join() on them. Once again: join() doesn't start execution of thread in given place, but waits for it to terminate (or just returns, if it's already terminated).