一、临界资源
保护临界资源的手段- 加锁会导致运行时间的增长
二、互斥锁
#include <stdio.h>
#include <thread>
#include <mutex>
// 临界资源
int num = 0;
std::mutex _mutex;
// 生产者
void producer() {
for (int i = 0; i < 1e7; i++)
{
_mutex.lock();
num += 1;
_mutex.unlock();
}
}
// 消费者
void comsumer() {
for (int i = 0; i < 1e7; i++)
{
_mutex.lock();
num -= 1;
_mutex.unlock();
}
}
int main() {
printf("Start in main function.");
std::thread pro_thread(producer), coms_thread(comsumer);
pro_thread.join();
coms_thread.join();
printf("Print in main function: num = %d\n", num);
return 0;
}
三、自旋锁
-
实验发现【自旋锁】的效率较高
自旋锁
- 自旋锁加入休眠的话会产生
死锁
#include <stdio.h>
#include <thread>
#include <atomic>
using namespace std;
using namespace this_thread;
using namespace chrono;
class Spin_lock
{
public:
Spin_lock() = default;
Spin_lock(const Spin_lock&) = delete;
Spin_lock& operator=(const Spin_lock&) = delete;
~Spin_lock() = default;
void lock();
void unlock();
private:
std::atomic_flag flag;
};
void Spin_lock::lock()
{
while (flag.test_and_set());
}
void Spin_lock::unlock()
{
flag.clear();
}
Spin_lock spinlock;
// 临界资源
int num = 0;
// 生产者
void producer() {
for (int i = 0; i < 1e4; i++)
{
spinlock.lock();
num += 1;
spinlock.unlock();
}
}
// 消费者
void comsumer() {
for (int i = 0; i < 1e4; i++)
{
spinlock.lock();
num -= 1;
sleep_for(milliseconds(100));
spinlock.unlock();
}
}
int main() {
printf("Start in main function.");
std::thread pro_thread(producer), coms_thread(comsumer);
pro_thread.join();
coms_thread.join();
printf("Print in main function: num = %d\n", num);
return 0;
}
参考博客
四、读写锁
读写锁介绍五、条件变量
-
条件变量是允许线程睡眠的
条件变量
条件变量需要配合
条件变量互斥量
来使用
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
const int MAX_BUF = 100;
int num = 0;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* producer(void*)
{
while (1)
{
pthread_mutex_lock(&mutex);
while (num >= MAX_BUF)
{
// wait and sleep
printf("buffer is enough, so wait consumer to save..\n");
pthread_cond_wait(&cond, &mutex);
}
num += 1;
printf("Produce a product, current product's num is: %d\n", num);
sleep(1);
pthread_cond_signal(&cond);
printf("inform consumer\n");
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void* consumer(void*)
{
while (1)
{
pthread_mutex_lock(&mutex);
while (num <= 0)
{
// wait and sleep
printf("buffer is null, so wait producer to save..\n");
pthread_cond_wait(&cond, &mutex);
}
num -= 1;
printf("Consume a product, current product's num is: %d\n", num);
sleep(1);
pthread_cond_signal(&cond);
printf("inform producer..\n");
pthread_mutex_unlock(&mutex);
}
}
int main()
{
printf("Start in main function.\n");
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &consumer, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Print in main function: num = %d\n", num);
return 0;
}
六、线程同步总结
锁的总结对比
网友评论