项目网站的建设有两种模式,django网站开发规范,安装了两个wordpress,嘉兴网站关键词排名目录 一、条件变量
1.什么是条件变量
故事说明
2、为什么需要使用条件变量
竞态条件 3.什么是同步
饥饿问题
二、条件变量的接口
1.pthread_cond_t
2.初始化#xff08;pthread_cond_init#xff09;
3.销毁#xff08;pthread_cond_destroy#xff09;
4.等待pthread_cond_init
3.销毁pthread_cond_destroy
4.等待pthread_cond_wait
5.唤醒pthread_cond_signal pthread_cond_broadcast
pthread_cond_signal
pthread_cond_broadcast
三、使用演示 模拟生产者消费者模式 一、条件变量
1.什么是条件变量 条件变量Condition Variable是一种用于线程同步的机制通常与互斥锁Mutex一起使用。条件变量提供了一种线程间的通信机制允许一个线程等待另一个线程满足某个条件后再继续执行。 故事说明 现在小明要在在一张桌子上放一个苹果而旁边有一群蒙着眼睛的人因为他们的眼睛被蒙着他们如果想拿到这个苹果就会时不时来桌子前摸一摸看看桌子是否有苹果并且谁来桌子前摸苹果是无序的这时的场面就很混乱小明一看不行于是小明就桌子上放了个铃铛并且组织需要苹果的人排好队有苹果小米就会摇响铃铛排在第一个的人就拿走苹果排到队尾等待被唤醒。此时混乱的场面就显得尽然有序了。在本故事中小明就是操作系统苹果就是临界资源一群蒙着眼睛都人就是多线程铃铛就是条件变量排队就是实现同步摇响铃铛就是唤醒线程。 2、为什么需要使用条件变量 使用条件变量主要是因为它们提供了在多线程编程中一种有效的同步机制。当多个线程需要等待某个特定条件成立才能继续执行时条件变量就显得尤为重要。通过条件变量线程可以安全地进入等待状态直到被其他线程显式地唤醒或满足等待的条件。这有助于避免线程的无谓轮询或忙等待提高了系统的响应能力和效率。 注意在使用条件变量时必须确保与互斥锁一起使用以避免竞态条件的发生。 竞态条件 竞态条件Race Condition是指在设备或系统尝试同时执行两个或多个操作时由于操作顺序不当而导致的不期望的结果。简单来说就是因为时序问题而导致程序异常。 3.什么是同步 在保证数据安全的前提下让线程能够按照某种特定的顺序访问临界资源从而有效避免饥饿问题叫做同步。 饥饿问题 饥饿问题指的是某些线程由于某种原因无法获得它们所需要的资源或执行机会导致它们长时间得不到处理甚至永远得不到处理的现象。这种情况通常发生在多个线程竞争有限资源时其中一些线程可能因为优先级过低、调度算法的不公平性、同步机制使用不当或其他原因而无法获得足够的执行时间。 二、条件变量的接口
1.pthread_cond_t pthread_cond_t 是 POSIX 线程库Pthreads中用于表示条件变量的数据类型。 2.初始化pthread_cond_init 功能初始化条件变量 原型 #include pthread.h 方式一pthread_cond_t是局部全局都可以用 int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); 方式二pthread_cond_t是全局变量时 pthread_cond_t cond PTHREAD_COND_INITIALIZER; 注意restrict 是一个类型限定符它用于告知编译器两个指针不会指向同一个内存位置这样编译器可以生成更高效的代码 参数 cond一个指向 pthread_cond_t 类型的指针用于存储初始化后的条件变量。attr一个指向 pthread_condattr_t 类型的指针用于指定条件变量的属性。通常可以传递 NULLnullptr以使用默认属性。 返回值 如果成功返回 0。如果失败返回错误码。 使用例子 #include pthread.h
#include stdio.h pthread_cond_t cond; // 全局 pthread_cond_t 变量 int main() { int rc; // 显式初始化全局 pthread_cond_t 变量 rc pthread_cond_init(cond, NULL); if (rc ! 0) { printf(Cond init failed: %d\n, rc); return 1; } // ... 其他代码包括线程创建和同步 ... // 在不再需要条件变量时销毁它 //...return 0;
} 3.销毁pthread_cond_destroy 功能销毁条件变量 原型 #include pthread.h int pthread_cond_destroy(pthread_cond_t *cond); 参数 cond指向要销毁的条件变量的指针。 返回值 如果成功返回 0。如果失败返回错误码。 4.等待pthread_cond_wait 功能阻塞当前线程直到指定的条件变量被其他线程信号通知或广播。 原型 #include pthread.h int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); 参数 cond指向条件变量的指针。mutex指向互斥锁的指针该互斥锁应该在调用 pthread_cond_wait 之前由当前线程锁定。 返回值 如果成功返回 0。如果失败返回错误码。 5.唤醒pthread_cond_signal pthread_cond_broadcast
pthread_cond_signal 功能唤醒正在等待特定条件变量的一个线程 原型 #include pthread.h int pthread_cond_signal(pthread_cond_t *cond); 参数 cond指向要发送信号广播的条件变量的指针。 返回值 如果成功返回 0。如果失败返回错误码。 pthread_cond_broadcast 功能用于唤醒所有正在等待指定条件变量的线程 原型 #include pthread.h int pthread_cond_broadcast(pthread_cond_t *cond); 参数 cond指向要发送信号广播的条件变量的指针。 返回值 如果成功返回 0。如果失败返回错误码。 三、使用演示 模拟生产者消费者模式 说明模拟生产者消费者模式 注意使用pthrad原生线程库POSIX库要链接库-lpthread 不会连接动态库的可以看我这篇文章[Linux]动静态库什么是动静态库怎么生成动静态库怎么使用连接动静态库-CSDN博客 cond.cc
#include iostream
#include pthread.h
#include vector
#include string
#include unistd.h
using namespace std;// 定义条件变量和互斥锁
// 全局的初始化方式
pthread_cond_t cond_var PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER;// 共享变量用于线程间的同步
int shared_data 0;// 线程函数模拟生产者
void *producer(void *args)
{string producer_name static_castchar *(args);// 生产数据并通知消费者while (1){// 锁定互斥锁pthread_mutex_lock(mutex);// 生产数据这里只是简单地递增shared_datashared_data;cout I is producer_name Producer produced data: shared_data endl;// 唤醒等待的消费者线程pthread_cond_signal(cond_var);// 解锁互斥锁pthread_mutex_unlock(mutex);// 模拟生产耗时sleep(1);}return nullptr;
}// 线程函数模拟消费者
void *consumer(void *args)
{string consumer_name static_castchar *(args);// 消费数据while (1){// 锁定互斥锁pthread_mutex_lock(mutex);// 等待生产者生产数据while (shared_data 0){// 等待条件变量解锁互斥锁进入等待状态pthread_cond_wait(cond_var, mutex);}// 消费数据这里只是简单地递减shared_datashared_data--;cout I is consumer_name Consumer consumed data: shared_data endl;cout ----------------------------------- endl;// 解锁互斥锁pthread_mutex_unlock(mutex);// 模拟消费耗时sleep(4);}return nullptr;
}int main()
{int producer_thread_num 5; // 生产者人数int consumer_thread_num 10; // 消费者人数vectorpthread_t producers;vectorpthread_t consumers;for (int i 0; i producer_thread_num; i){pthread_t producer_thread; // 生产者char buffer[64];sprintf(buffer, producer-%d, i 1);// 创建生产者线程if (pthread_create(producer_thread, nullptr, producer, buffer) ! 0){perror(pthread_create producer);exit(EXIT_FAILURE);}producers.push_back(producer_thread);//保存pthread_t以备等待回收}for (int i 0; i consumer_thread_num; i){pthread_t consumer_thread; // 消费者// 创建消费者线程char buffer[64];sprintf(buffer, consumer-%d, i 1);if (pthread_create(consumer_thread, nullptr, consumer, buffer) ! 0){perror(pthread_create consumer);exit(EXIT_FAILURE);}consumers.push_back(consumer_thread);//保存pthread_t以备等待回收}// 等待线程结束for (auto thraed:producers){ pthread_join(thraed, nullptr);}for (auto thraed:consumers){ pthread_join(thraed, nullptr);}// 销毁条件变量pthread_cond_destroy(cond_var);// 销毁锁pthread_mutex_destroy(mutex);return 0;
}
Makefile
mycond:cond.ccg -o $ $^ -stdc11 -lpthread
PHONY:clean
clean:rm -f mycond
结果