Finish std::thread from another thread

Started by
14 comments, last by swiftcoder 6 years ago

Basically i create a thread and detach it, after some time i would like to exit it, i made a global variable that informs thread that it needs to be finished, however it never quits i believe it has something to do with sharing one var with two different threads (not attached to each other), one day i read about std::atomic that it somehow manages reads/writes but im not even aware how to declare/use it.

 

And heres the code


void CreateDWMTCPServer(int prt)
{
	if (server != 0)
	{
		

		server_thread_finished = true;
		while ( (!server_thread_free) && (server_thread_created)) {} // holds here forever
		delete server;
		server = 0;
		server_thread_created = false;
	}
		PUSH_EVENT(event_display, "creating server...");
	
	server = new TTCPWindowLayerServer();
	server->CreateServer(prt);
	server_thread_created = true;
	 std::thread ServerThread(std::bind(&TDWM::ProcessServerFrame, this));
	 ServerThread.detach();
	
}

Code above isnexecuted from main thread

 

Now thread code



void ProcessServerFrame()
{
	if (server == 0) return;
	server_thread_free = false;
	
	
	while ( !server_thread_finished )
	{
		if (server_thread_lock_buffer_active) continue;
	
	
	server->ProcessFrame(); //add any pending data to pdata buffer stream, accept or disconnect clients and thats all

	
	TCPWindowLayerClient * p = server->clients;
	
	while (p != 0)
	{
		if (p->LAST_EVENT == TCP_DATA_RECEIVED)
		{
		AddCommandsToDWMEvent(p);
    	ProcessPendingPackets(&events, Forms);
			p->ppos = 0;
			p->LAST_EVENT = TCP_NO_ACTION;
		}

		p = p->next;
	}

	
	}


	


	server->Close();
	server_thread_free = true;
	KillServer();

	
}

As you can see theres a bool server_thread_finished (not to mention bad naming) that informs loop in a thread to stop executing this is main shared variable

After while loop thread changes another global variable server_thread_free so that while loop in main thread knows when to break, however it seems they are not switched cause std::thread uses var when main thread wants to update it, so how would i fix this sharing memory problem?

Notice 

while ( (!server_thread_free) && (server_thread_created)) {}

In first chunk of code

Advertisement

Are you sure that `server_thread_created` is equal to true the first time through this function?

Both threads should be seeing your writes just fine, though there may be more subtle issues lurking. 

If you want to use atomics, its as simple as replacing `bool` with `std::atomic_bool`.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

server_thread_finished is set to true, same fir server_thread_created, so theres an issue inside thread void, that it doesnt exit... :|

 

I just changed bool to std::atomic_bool, but the result is the same do i need some extra actions like using std::mutex or any other things?

std::atomic is useless here, I use siple bool too and it works for my thread-pool and tasking system so isnt the issue.

Are you sure that your 'server thread' is in a state that it actaully can finish? Some calls to IOCP or waiting sockets may stall until there is data to be processed. Maybe you need to send an event or tell your server's socket that it dosent need to listen anymore?

Server->ProcessFrame();

Is blocking while loop in a thread

7 hours ago, Cat's machete said:

I just changed bool to std::atomic_bool, but the result is the same do i need some extra actions like using std::mutex or any other things?

This isn't a tech problem, it's a logic problem. Your thread is for some reason not able to complete, or possibly never makes it back through the while loop to recheck the variable.

Add a little printf-debugging. Print the value of `server_thread_finished` each time the thread enters the while loop, see if it's actually be rechecked regularly, and if it's seeing the value change.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Anyway i'm having problems debugging anything within a thread, i thought i could save a log to a file, but instead of writing text i get blank lines, maybe theres a good way to log a thread?

18 minutes ago, Cat's machete said:

i thought i could save a log to a file, but instead of writing text i get blank lines

You are going to have to show some code. Writing a file works the same regardless of what thread it's on.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Ok, but first of all ill have to check out how to use select function, it seems even when it worked in the past im getting errors there, and i know that it should write so thats the big question here may be something with saving function so ill post that


typedef std::string AnsiString;



#ifndef WINDOWS_CMP
struct TStringList
#endif
{

	int Count;
std::vector<AnsiString> Strings;


void Add(AnsiString text)
{
AnsiString p = text;
Strings.push_back(text);
	Count = Count + 1;
}

	AnsiString GetText()
	{
	AnsiString res = "";
	int i;
	for (i=0; i < Count; i++)
		res = res + Strings[i] + "\n";
	return res;
	}
	
	
	AnsiString pc;

void SaveToFile(AnsiString fname)
{
	pc = GetText();
	std::ofstream outfile (fname.c_str(),std::ofstream::binary);
	int len = pc.length();
	char * buff = new char[ len ];
	memcpy(buff, pc.c_str(), sizeof(char) * len);
	outfile.write (buff, len);
	outfile.close();
}
};






now where i log that in my server class like it
void LOG(AnsiString str)
{
	pstdout.Add(str);
	pstdout.SaveToFile("/mnt/ext_sdcard/server_log.txt");
}


and use it like (ofc in a thread)

LOG("TEXT 1");
call some func
LOG("TEXT 2");
do other stuff
LOG("TEXT 3");

 

Ok, well, this will blow up horribly in a multithreaded scenario, because you are manipulating a container on multiple threads. I don't get what the vector of strings is supposed to buy you anyway, since you write the complete file every time you log (hence overwriting all previous log messages in the process).

Simplify all of this. Open the file once in append mode at the beginning of the program, keep it open, write a single string to it and flush within each LOG invocation.

Despite the standard not explicitly guaranteeing ofstream to be thread safe, single line writes will not break on any implementation I am aware of, so you can probably share a single file between threads without issue. But if you are worried about that, either wrap the log function with a std::lock_guard, or open one file per thread.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement