c++ 精简版 thread

mutex.h // MinGW 4.7 暂不支持 <mutex>,临时用这个代替

// MinGW doesn't provide <mutex> ...
#pragma once
namespace std {

struct once_flag {
	bool f;
	once_flag(bool f = false) : f(f) {}
};
template<typename fn_t, typename... args_t>
void call_once(once_flag& flag, fn_t fn, args_t... args) {
	if(!flag.f) {
		flag.f = true;
		fn(args...);
	}
}

}

thread.h

#pragma once

#include <windows.h>
#include <functional>
#include <stdexcept>
using namespace std;

#include "mutex.h"

typedef unsigned long ulong;

namespace threading {


struct thread;
ulong WINAPI ThreadFunc(void* thrd);
thread* get_current_thread_data();
void interruption_point();

// #define TLS_OUT_OF_INDEXES 0xFFFFFFFF
ulong current_thread_tls_key = TLS_OUT_OF_INDEXES;


struct interrupt_exception {};

struct thread_data {
	bool interrupted;
	typedef function<void()> f_type;
	f_type _f;

	thread_data() : interrupted(false) {}

	template<typename F>
	thread_data(F f) : _f(f), interrupted(false) {}

	void run() {
		if(_f) _f();
	}
};


struct thread {
	thread_data _data;
	HANDLE _h;
	ulong _id;

	thread() {}
	thread(thread_data data) : _data(data) {}

	void start() {
		_h = CreateThread(NULL, 0, ThreadFunc, (void*)this, 0, &_id);
	}
	void join() {
		::WaitForSingleObject(_h, INFINITE);
	}
	void operator=(thread_data data) {
		_data = data;
	}
	void interrupt() {
		_data.interrupted = true;
	}
};

std::once_flag thread_tls_once_flag;

ulong WINAPI ThreadFunc(void* thrd) {
	std::call_once(thread_tls_once_flag, [&]() {
		current_thread_tls_key = TlsAlloc();
	});
	if(current_thread_tls_key == TLS_OUT_OF_INDEXES)
		throw std::runtime_error("tls alloc error");

	if(!::TlsSetValue(current_thread_tls_key, thrd)) 
		throw std::runtime_error("tls setvalue error");
	
	try {
		static_cast<thread*>(thrd)->_data.run();
	} catch(interrupt_exception&) {}
	return 0;
}
void interruption_point() {
	thread* thrd = get_current_thread_data();
	if(!thrd) throw std::runtime_error("no thread, wth");
	if(thrd->_data.interrupted) {
		thrd->_data.interrupted = false;
		throw interrupt_exception();
	}
}
thread* get_current_thread_data() {
	if(current_thread_tls_key == TLS_OUT_OF_INDEXES) {
		return NULL;
	}
	return (thread*)TlsGetValue(current_thread_tls_key);
}

}; // end of namespace thread

  

test:

#include <iostream>
using namespace std;

#include "../include/thread.h"
using namespace threading;

void S1() {
	while(1) {
		interruption_point();
		cout << "S1()" << endl;
		Sleep(1000);
	}
}
void S2() {
	while(1) {
		interruption_point();
		cout << "S2()" << endl;
		Sleep(500);
	}
}

int main() {
	thread t1(S1);
	thread t2;
	t2 = S2;
	thread t3([&]() {
		Sleep(2000);
		t2.interrupt();
		t2.join();
		Sleep(2000);
		t2.start();
		cout << "t3 over" << endl;
	});

	t1.start();
	t2.start();
	t3.start();

	t1.join();
	t2.join();
}

  

原文链接: https://www.cnblogs.com/aj3423/archive/2012/11/05/3150502.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++ 精简版 thread

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/68171

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午1:13
下一篇 2023年2月9日 下午1:13

相关推荐