当前位置: 首页 > wzjs >正文

建设门户网站的目的和需求网站如何开通支付功能

建设门户网站的目的和需求,网站如何开通支付功能,网站高端建设开发公司,旅游网站模板面试聊到锁,只知道数据库的读锁,不了解编程中的读锁,也没谈,遂败北。 代码分 C 和 POSIX 版本 文章目录 互斥锁读写锁自旋锁递归锁超时锁原子操作条件变量信号量 互斥锁 互斥锁是最基本的线程同步工具,确保同一时刻只…

面试聊到锁,只知道数据库的读锁,不了解编程中的读锁,也没谈,遂败北。

代码分 C++ 和 POSIX 版本

文章目录

      • 互斥锁
      • 读写锁
      • 自旋锁
      • 递归锁
      • 超时锁
      • 原子操作
      • 条件变量
      • 信号量

互斥锁

互斥锁是最基本的线程同步工具,确保同一时刻只有一个线程可以访问共享资源。

如果加锁失败,锁被别人持有,该线程会阻塞,即不占用CPU资源,直至拿到锁。

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void worker() {// 使用 lock() 方法,若锁被占用则阻塞mtx.lock();std::cout << "Thread " << std::this_thread::get_id() << " has the lock." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));std::cout << "Thread " << std::this_thread::get_id() << " is releasing the lock." << std::endl;mtx.unlock();// 使用 try_lock() 方法,若锁被占用则返回 falseif (mtx.try_lock()) {std::cout << "Thread " << std::this_thread::get_id() << " acquired the lock using try_lock." << std::endl;mtx.unlock();} else {std::cout << "Thread " << std::this_thread::get_id() << " failed to acquire the lock using try_lock." << std::endl;}
}int main() {std::thread t1(worker);std::thread t2(worker);t1.join();t2.join();return 0;
}
#include <pthread.h>pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;void *thread_func(void *arg) {pthread_mutex_lock(&lock);   // 加锁// 访问共享资源pthread_mutex_unlock(&lock); // 解锁return NULL;
}pthread_mutex_trylock()的方式可以立即返回~

读写锁

读写锁允许多个线程同时读取共享资源,但写操作需要独占。

C++17 是对 shared_mutex 进行 std::shared_lock<> 和 std::unique_ptr<> 这两个lock_guard实现的。

#include <iostream>
#include <thread>
#include <shared_mutex>std::shared_mutex rwMutex;
int sharedData = 0;void reader() {std::shared_lock<std::shared_mutex> lock(rwMutex);std::cout << "Reader reads: " << sharedData << std::endl;
}void writer() {std::unique_lock<std::shared_mutex> lock(rwMutex);++sharedData;std::cout << "Writer writes: " << sharedData << std::endl;
}int main() {std::thread r1(reader);std::thread w1(writer);r1.join();w1.join();return 0;
}    
#include <pthread.h>pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;void *reader(void *arg) {pthread_rwlock_rdlock(&rwlock); // 读锁// 读取共享资源pthread_rwlock_unlock(&rwlock); // 解锁return NULL;
}void *writer(void *arg) {pthread_rwlock_wrlock(&rwlock); // 写锁// 修改共享资源pthread_rwlock_unlock(&rwlock); // 解锁return NULL;
}

自旋锁

线程在获取锁失败时不会进入休眠,而是持续尝试获取锁。
避免了线程上下文切换的开销,适合锁持有时间极短(如几十到几百个 CPU 周期)的场景。多核 CPU 环境且锁竞争不激烈时效果最佳

像互斥锁,会让出CPU,这会交换上下文。最后还要换回来,如果等待时间小于两次交换上下文的时间,那等待就是更高效的。

C++ 模拟 【自旋锁的"忙等待"与"混合模式"的权衡】

#include <iostream>
#include <thread>
#include <atomic>class SpinLock {
private:std::atomic<bool> flag = false;
public:void lock() {while (flag.exchange(true, std::memory_order_acquire)) {while (flag.load(std::memory_order_relaxed)) {std::this_thread::yield();}}}void unlock() {flag.store(false, std::memory_order_release);}
};SpinLock spinLock;
void spinWorker() {spinLock.lock();std::cout << "Spin lock acquired by thread: " << std::this_thread::get_id() << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(100));spinLock.unlock();
}int main() {std::thread s1(spinWorker);std::thread s2(spinWorker);s1.join();s2.join();return 0;
}    
  • exchange是原子类的替换值操作
    std::memory_order_acquire:这是内存序的一种,用于保证在 exchange 操作之后的所有读写操作不会被重排到 exchange 操作之前,从而确保在获取锁之后对共享资源的访问是安全的。(不会出现先访问共享资源再获取锁的情况,从而确保了对共享资源的安全访问。)【如果学过计算机系统的MIPS,就应该了解流水线,一个道理】

  • load 函数:std::atomic 类的成员函数,用于获取 flag 的当前值。
    std::memory_order_relaxed:这是一种宽松的内存序,只保证原子性,不保证任何顺序性。在这里使用宽松内存序是因为在这个内层循环中,主要目的是快速检查锁的状态,对内存顺序的要求不高,使用宽松内存序可以提高性能。
    std::this_thread::yield() 让出 CPU 时间片

#include <pthread.h>pthread_spinlock_t spinlock;void *worker(void *arg) {pthread_spin_lock(&spinlock);   // 自旋加锁// 访问共享资源pthread_spin_unlock(&spinlock); // 解锁return NULL;
}

递归锁

初始化的时候设置。
自己调用自己,加同一个锁。

#include <iostream>
#include <thread>
#include <recursive_mutex>std::recursive_mutex recursiveMutex;void recursiveWorker(int depth) {if (depth == 0) return;std::lock_guard<std::recursive_mutex> lock(recursiveMutex);std::cout << "Recursive lock acquired at depth " << depth << " by thread: " << std::this_thread::get_id() << std::endl;recursiveWorker(depth - 1);
}int main() {std::thread rw(recursiveWorker, 3);rw.join();return 0;
}    

POSIX 初始化普通锁:

#include <pthread.h>
#include <stdio.h>pthread_mutex_t lock;void functionA() {pthread_mutex_lock(&lock);printf("Function A: Locked\n");functionA();  // ✅ 不会死锁,因为递归锁允许同一线程重复加锁pthread_mutex_unlock(&lock);printf("Function A: Unlocked\n");
}int main() {pthread_mutexattr_t attr;pthread_mutexattr_init(&attr);pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);pthread_mutex_init(&lock, &attr);functionA();  // 正常执行return 0;
}

超时锁

在尝试获取互斥锁时,如果锁没有在指定的 超时时间内 被获取到,线程就会放弃等待并继续执行。

超时(超过 2 秒)仍未获取到锁,它会返回非 0 值

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>std::timed_mutex tmtx;void worker() {// 尝试在 2 秒内获取锁if (tmtx.try_lock_for(std::chrono::seconds(2))) {std::cout << "Thread " << std::this_thread::get_id() << " acquired the lock using try_lock_for." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));tmtx.unlock();} else {std::cout << "Thread " << std::this_thread::get_id() << " failed to acquire the lock using try_lock_for." << std::endl;}
}int main() {std::thread t1(worker);std::thread t2(worker);t1.join();t2.join();return 0;
}
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>pthread_mutex_t lock;void* threadFunc(void* arg) {printf("Thread: Trying to lock...\n");struct timespec timeout;clock_gettime(CLOCK_REALTIME, &timeout);timeout.tv_sec += 2;  // 设置超时时间(2 秒)if (pthread_mutex_timedlock(&lock, &timeout) == 0) {printf("Thread: Locked!\n");pthread_mutex_unlock(&lock);} else {printf("Thread: Lock timeout! Giving up.\n");}return NULL;
}int main() {pthread_mutex_init(&lock, NULL);pthread_mutex_lock(&lock);  // 主线程加锁pthread_t thread;pthread_create(&thread, NULL, threadFunc, NULL);sleep(5);  // 模拟主线程长时间占有锁pthread_mutex_unlock(&lock);pthread_join(thread, NULL);return 0;
}

原子操作

一定要谈是操作该变量时

#include <iostream>
#include <thread>
#include <atomic>std::atomic<int> atomic_counter(0);
void atomic_worker() {for (int i = 0; i < 1000; ++i) {atomic_counter.fetch_add(1, std::memory_order_relaxed);}
}int main() {std::thread a1(atomic_worker);std::thread a2(atomic_worker);a1.join();a2.join();std::cout << "Atomic counter value: " << atomic_counter.load() << std::endl;return 0;
}    
#include <stdatomic.h>atomic_int counter = 0;void *worker(void *arg) {atomic_fetch_add(&counter, 1); // 原子递增return NULL;
}

条件变量

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex cvMutex;
std::condition_variable cv;
bool ready = false;void waiter() {std::unique_lock<std::mutex> lock(cvMutex);cv.wait(lock, [] { return ready; });std::cout << "Waiter thread is notified." << std::endl;
}void notifier() {std::this_thread::sleep_for(std::chrono::milliseconds(200));{std::lock_guard<std::mutex> lock(cvMutex);ready = true;}cv.notify_one();std::cout << "Notifier thread sent notification." << std::endl;
}int main() {std::thread w(waiter);std::thread n(notifier);w.join();n.join();return 0;
}    
#include <pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready = 0; // 共享状态void *consumer(void *arg) {pthread_mutex_lock(&mutex);while (ready == 0) {pthread_cond_wait(&cond, &mutex); // 等待条件满足}// 处理数据pthread_mutex_unlock(&mutex);return NULL;
}void *producer(void *arg) {pthread_mutex_lock(&mutex);ready = 1;pthread_cond_signal(&cond); // 唤醒等待线程pthread_mutex_unlock(&mutex);return NULL;
}

信号量

信号量可以控制多个线程同时访问资源的数量,比如限制访问数据库连接池的线程数。

#include <iostream>
#include <thread>
#include <semaphore>std::counting_semaphore<1> semaphore(0);void producer() {std::this_thread::sleep_for(std::chrono::milliseconds(200));std::cout << "Producer is releasing semaphore." << std::endl;semaphore.release();
}void consumer() {std::cout << "Consumer is waiting for semaphore." << std::endl;semaphore.acquire();std::cout << "Consumer acquired semaphore." << std::endl;
}int main() {std::thread p(producer);std::thread c(consumer);p.join();c.join();return 0;
}    
#include <semaphore.h>sem_t sem;void *worker(void *arg) {sem_wait(&sem);  // 获取信号量// 访问资源sem_post(&sem);  // 释放信号量return NULL;
}int main() {sem_init(&sem, 0, 3); // 允许最多3个线程同时访问return 0;
}
http://www.dtcms.com/wzjs/601189.html

相关文章:

  • 寿光市建设局网站网站建设怎么配置伪静态文件
  • 网站建设公司crm系统中山企业网站推广
  • 网站性能优化网站开发用到的技术
  • 广水市建设局网站天津企业网站建设一般多少钱
  • 公司做一个网站中国核工业第五建设有限公司待遇
  • 网站代建设费用吗公司网站建设管理意见
  • 免费微网站建站系统源码wordpress前台后台都空白
  • 易瑞通网站建设wordpress前面头部目录框
  • 免费论文网站大全桂阳网站定制
  • 网站主页模板西安网站建设gj
  • 做英剧网站的设计思路网站开发费用
  • 郑州工程建设信息网站刚注册公司怎么做网站
  • 电子商务网站建设作业文档东莞网站制作培训多少钱
  • 做水果网站行精准营销方式有哪些
  • 网站开发用工工程师柳州正规网站建设招商
  • dw做网站怎么发布网站建设公司广
  • 网站排名怎么优化网站站群怎么做
  • 怎样让网站排名优化工鞍山市残疾人网站开发
  • 建设网站的功能及目的怎么查百度收录
  • 免费网页视频下载器seo需要什么技术
  • 网站开发评估与调整莱芜新闻最新消息
  • 天津专业的网站建设公司淘客cms网站建设
  • 主营商城网站建设临沂做网站
  • 富阳网站开发南通专业家纺网站建设
  • 维启网站建设网站建设公司源码 asp
  • 外贸网站建设优化外链推广网站都有哪些
  • 天津塘沽网站建设用focusky做h5微网站
  • 文登区城乡建设局网站餐饮企业网站开发背景
  • 域名和网站的建设实训报告网站网页设计招聘
  • 沈阳创新网站建设报价成立公司注意事项