目录
引言
我们已经学习了线程操作,知道了线程的相关系统调用。但是在线程中一定会有一些安全问题,现在我们给与一个场景:当我们给一些线程派发抢车篇的任务时,也就是说让多个线程访问同一份资源时,会怎么样呢?我们通过一个代码来模拟抢车票的过程。
首先C++11中对我们Linux中的pthread库进行了封装,我们自己模拟了一份thread库:
#ifndef __THREAD_HPP__
#define __THREAD_HPP__
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <functional>
using namespace std;
namespace ThreadModule
{
template <typename T>
using func_t = function<void(T)>;
template <typename T>
class Thread
{
public:
Thread(func_t<T> func, T &data, const string name = "none-name")
: _func(func), _data(data), _threadname(name), _stop(true)
{
}
void Excute()
{
_func(_data);
}
static void *threadtoutine(void *args)
{
Thread<T> *self = static_cast<Thread<T>*>(args);
self->Excute();
return nullptr;
}
bool Start()
{
int n = pthread_create(&_tid, nullptr, threadtoutine, this);
if (!n)
{
_stop = false;
return true;
}
else
{
return false;
}
}
void Detach()
{
if (!_stop)
{
pthread_detach(_tid);
}
}
void Join()
{
if (!_stop)
{
pthread_join(_tid,nullptr);
}
}
std::string name()
{
return _threadname;
}
void Stop()
{
_stop = true;
}
~Thread()
{
}
private:
pthread_t _tid;
string _threadname;
T _data;
func_t<T> _func;
bool _stop;
};
}
#endif
我们使用我们自己的thread库模拟了抢车票的任务:
#include <iostream>
#include <unistd.h>
#include <vector>
#include "Thread.hpp"
using namespace std;
using namespace ThreadModule;
int g_tickets = 10000;
const int num = 4;
class ThreadData
{
public:
ThreadData(int &tickets, const std::string &name)
: _tickets(tickets), _name(name), _total(0)
{
}
~ThreadData()
{
}
public:
int &_tickets; // 所有的线程,最后都会引用同一个全局的g_tickets
std::string _name;
int _total;
};
void route(ThreadData *td)
{
while (true)
{
{
if (td->_tickets > 0) // 1
{
usleep(1000);
printf("%s running, get tickets: %d\n", td->_name.c_str(), td->_tickets); // 2
td->