zoukankan      html  css  js  c++  java
  • 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();
    }
    

      

  • 相关阅读:
    Pascal's Triangle II
    Pascal's Triangle
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Populating Next Right Pointers in Each Node
    path sum II
    Path Sum
    [转载]小波时频图
    [转载]小波时频图
    [转载]Hilbert变换及谱分析
  • 原文地址:https://www.cnblogs.com/aj3423/p/3150502.html
Copyright © 2011-2022 走看看