如何创建启动一个线程
std::thread创建一个线程对象,传入线程所需要的的线程函数和参数,线程自动开始执行。
void threadHandle1()
{
//子线程等待两秒
std::this_thread::sleep_for(std::chrono::seconds(2));
cout << "hello thread1" << endl;
}
int main()
{
//定义了一个线程对象 传入一个线程函数 新线程开始运行
std::thread t1(threadHandle1);
//主线程等待子线程结束 主线程继续
//t1.join();
//把子线程设置为分离线程
t1.detach();
cout << "main thread" << endl;
return 0;
}
通过加锁来解决多线程问题
static int count = 100;
std::mutex tex; //互斥锁
void sellTicket(int index)
{
while (::count > 0) //count==1 锁+双重判断
{
tex.lock();
if (::count > 0)
{
cout << "chuangkou" << index << "卖出" << ::count << endl;
//cout << ::count << endl;
::count--;
}
tex.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
list<std::thread> t;
for (int i = 0; i < 3; i++)
{
t.push_back(std::thread(sellTicket, i));
}
for (std::thread &v : t)
{
v.join();
}
cout << "main thread" << endl;
return 0;
}
生产者与消费者
以下代码存在如果消费者消费过快,生产者还没有生产出来,会导致queue为-1,存在设计问题。
std::mutex mut;
class Queue
{
public:
void put(int val)
{
lock_guard<std::mutex> guard(mut);
q.push(val);
cout << "生产者 生产 " << val << endl;
}
int get()
{
lock_guard<std::mutex> guard(mut);
int val = q.front();
q.pop();
cout << "消费者 消费: " << val << endl;
return val;
}
private:
queue<int> q;
};
void product(Queue *que)
{
for (int i = 0; i < 10; i++)
{
que->put(i);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void consumer(Queue *que)
{
for (int i = 0; i < 10; i++)
{
que->get();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
Queue que; //两个线程共享的队列
std::thread t1(product,&que);
std::thread t2(consumer,&que);
t1.join();
t2.join();
return 0;
}
采用线程间通信后
std::mutex mut;
std::condition_variable cv; //条件变量 线程间通信
class Queue
{
public:
void put(int val)
{
//lock_guard<std::mutex> guard(mut);
unique_lock<std::mutex> lck(mut);
while (!q.empty())
{
//通知消费者消费 消费了在接着生产 生产者线程应该进入等待状态 把mut互斥锁释放
cv.wait(lck); //wait只能是unique lock
}
q.push(val);
cv.notify_all(); //通知其他线程去消费
cout << "生产者 生产 " << val << endl;
}
int get()
{
//lock_guard<std::mutex> guard(mut);
unique_lock<std::mutex> lck(mut);
while (q.empty())
{
//等待 释放锁
cv.wait(lck);
}
int val = q.front();
q.pop();
cv.notify_all(); //通知其他线程去消费
cout << "消费者 消费: " << val << endl;
return val;
}
private:
queue<int> q;
};
void product(Queue *que)
{
for (int i = 0; i < 10; i++)
{
que->put(i);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void consumer(Queue *que)
{
for (int i = 0; i < 10; i++)
{
que->get();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
再谈unique_lock与lock_guard
lock_guard不能用于拷贝构造和赋值,所以不能用来函数参数传递和返回过程中。只能用于简单的临界区代码互斥操作。
unique_lock能用于简单的临界区代码互斥操作,还能在函数调用的过程中。