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

app设计网站有哪些功能网站编程培训班

app设计网站有哪些功能,网站编程培训班,网站开发w亿玛酷1负责,手机h5网站目录 死锁 什么是死锁 构成死锁的四个必要条件 如何避免死锁 线程同步 同步的引入 同步的方式 条件变量 条件变量的使用 整体代码 死锁 什么是死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源#xff0c;但因互相申请被其他进程所占用不会释放 的资源而处…目录 死锁 什么是死锁 构成死锁的四个必要条件 如何避免死锁 线程同步 同步的引入 同步的方式 条件变量 条件变量的使用 整体代码 死锁 什么是死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源但因互相申请被其他进程所占用不会释放 的资源而处于的一种永久等待状态. 例如进程两个锁mtx1和mtx2进程A执行某一段代码需要先申请mtx1再申请mtx2而进程B执行对应的代码需要现申请mtx2再申请mtx1. 某个时刻进程A和B同时运行进程A拿到了mtx1进程B拿到了mtx2但紧接着进程A需要mtx2但此时这把锁被进程B所占用无法申请便阻塞等待进程B的完成。而进程B需要mtx1但是此时被A占用需要等待进程A的完成也阻塞在了这里。于是便造成了死锁。 构成死锁的四个必要条件 互斥条件 一个资源每次只能被一个执行流使用其他进程无法同时访问该资源。请求与保持条件即进程在请求资源时可以保持已占有的资源即不释放自己原本的资源不剥夺条件已经获得资源的进程不能被强行剥夺其他进程所拥有的资源只有自愿释放循环等待条件若干进程之间形成一种头尾相连的循环等待资源关系。如A-B,B-A. 如何避免死锁 我们知道了构成死锁的那个四个必要条件只要破坏其中任意一个 条件即可 破坏互斥条件尽量避免使用互斥资源或者采用不同的资源访问方式如读写锁允许多个进程或线程同时访问某些资源。破坏请求与保持条件如果申请多个锁失败则释放自己已经拥有的资源。破坏不剥夺条件引入资源抢占机制即允许操作系统对进程已获得的资源进行抢占。当其他进程紧迫需要某个资源时系统可以终止或暂停某个进程将其持有的资源释放分配给需要的进程。 打破环路等待条件采用全局资源排序策略为每个资源指定一个唯一的编号然后要求进程只能按照编号递增的顺序请求资源这样可以避免环路等待的发生。 以上所说的资源都也可以理解为锁。 线程同步 同步的引入 上一章我们说的         1.多线程然后抢票的例子我们发现虽然有多个线程但是每一次基本上都是那一个线程在抢(比如优先级可能更高)其它线程抢不到这就是一个线程频繁地申请到资源造成别的线程饥饿问题。 2.假设一个资源暂时没有了而线程依旧在竞争锁然后访问资源访问不到然后释放锁没就这样一直进行但此时也没有资源可用。这样就太过于浪费了。 以上这些操作都是正确的但是是不合理的 所以为了解决上面这系列问题便引入了同步主要是为了解决 访问临界资源合理性问题的. 即按照一定的顺序进行临界资源的访问。 1.对于问题一我们可以这样当一个线程申请到资源后使用完之后排到其它线程后面让其他线程先访问如此进行下去。 2.对于问题二我们可以暂时每个线程发个号当有资源时再按照号的顺序来访问资源而不是互相不正当竞争这份资源 所以线程同步的是线程同步是指在并发编程中通过协调多个线程的执行顺序以及对共享资源的访问来保证线程之间的正确交互 同步的方式 条件变量 当我们申请临界资源时 --- 要对临界资源是否存在做检测 --- 检测的本质也是访问临界资源 ---结论对临界资源的检测也一定是在加锁和解锁之间的。 既然这样那检测依然需要频繁地申请和释放锁那么有没有办法让线程检测到资源不就绪的时候 a.不要让线程自己再频繁检测了而是等待 b.当条件就绪的时候通知对应的线程让它来进行资源的申请与访问。 为了满足上面的说话这里就有引入条件变量。 条件变量Condition Variable是一种同步原语常用于多线程编程中进行线程间的等待和通知。它用于实现线程之间的同步和协作使得一个线程可以等待某个条件的满足并被其他线程通知唤醒。 条件变量的使用 使用条件变量需要配合互斥锁pthread_mutex_t来保证线程的安全操作。一般的使用步骤如下 首先我们要先创建一个条件变量数据类型为 pthread_cond_t同时也要创建互斥锁。 pthread_mutex_t mtx;pthread_cond_t cond;初始化条件变量和互斥锁互斥锁我们说了初始化方式了这里说初始化条件变量的函数 pthread_cond_init该函数原型如下 int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr); 第一个参数为条件变量第二个参数为条件变量属性一般设为NULL。 如果创建的条件变量是全局的那么可以用下面的方法进行初始化 pthread_cond_t cond PTHREAD_COND_INITIALIZER;所以初始化代码如下  pthread_cond_init(cond,nullptr);//初始化条件变量pthread_mutex_init(mtx,nullptr);//初始化锁 紧接着我们创建4个线程然后再创建一个结构体里面包含了线程名该线程调用的方法条件变量和互斥锁然后编写一个构造函数来初始化这些 typedef void(*func_t)(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond); class ThreadData { public:ThreadData(const string name,func_t func,pthread_mutex_t* pmtx, pthread_cond_t* pcond):_name(name),_func(func),_pmtx(pmtx),_pcond(pcond){} public:string _name;//线程名func_t _func;//该线程对应的回调方法pthread_mutex_t* _pmtx;//互斥锁pthread_cond_t* _pcond;//条件变量 }; 然后开始编写每个线程的回调方法这里其实不能很好地展示条件变量中锁的作用我们需要在下一章生产者与消费者模型时才能好好看出作用. 这里每个线程方法我们先利用pthread_cond_wait进行阻塞等待当资源准备就绪的时候才会继续向后执行。然后后面输出一条语句 该函数原型如下 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 函数pthread_cond_wait用于使线程进入等待状态并且会原子性地释放由mutex指定的互斥锁进入等待状态后会阻塞等待直到其他线程使用相同的条件变量调用pthread_cond_signal或pthread_cond_broadcast时被唤醒并重新获得互斥锁。调用前需要确保已经加锁。返回时会重新获得互斥锁。 其中第一个参数为条件变量第二个参数为互斥锁。具体什么作用下节课会讲。 这是线程1的回调方法线程23,4都是同样地只不过名字不同。 void func1(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond) {while(true){pthread_mutex_lock(pmtx);//if(临界资源不就绪) wait之前一般会进行检测这里由于无法很好的模拟场景就暂时不加ifpthread_cond_wait(pcond,pmtx);//默认该线程在执行的时候wait代码被执行当前线程会立即被阻塞cout name running ... endl;pthread_mutex_unlock(pmtx);} } 现在创建好线程后每个线程都被阻塞在了pthread_mutex_wait接口这里所以我们需要再主函数中唤醒这些线程共有两种方式 pthread_cond_signal int pthread_cond_signal(pthread_cond_t *cond); 参数为条件变量至于唤醒哪一个线程这是由调度器决定的但顺序一定是固定的当我们运行起来程序后 这样便保证了线程同步。  这是一个一个线程的唤醒如果我们想唤醒所有线程这就需要用到pthread_cond_broadcast 该函数原型如下: int pthread_cond_broadcast(pthread_cond_t *cond); 参数同样也为条件变量函数pthread_cond_broadcast用于广播条件变量的信号即唤醒所有等待此条件变量的线程。 这样便一次能唤醒所有线程继续执行了。 一切完成之后我们需要在最后销毁释放条件变量和互斥锁函数为pthread_cond_destroy 函数原型为 int pthread_cond_destroy(pthread_cond_t *cond); 参数同样为定义的条件变量传进去之后即可释放条件变量。 整体代码 以上便是条件变量的一个大致使用流程具体的理解下一章生产者消费者模型会讲解这列理解了条件变量的用法即可。 可以拷贝到自己平台下运行编译时记得加上-lpthread如下 g -o mythread mythread.cc -lpthread 代码 #includeiostream #includestring #includestdlib.h #includeunistd.h #includepthread.husing namespace std;#define PTHREAD_NUM 4typedef void(*func_t)(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond); class ThreadData { public:ThreadData(const string name,func_t func,pthread_mutex_t* pmtx, pthread_cond_t* pcond):_name(name),_func(func),_pmtx(pmtx),_pcond(pcond){} public:string _name;func_t _func;pthread_mutex_t* _pmtx;pthread_cond_t* _pcond; };void func1(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond) {while(true){pthread_mutex_lock(pmtx);//if(临界资源不就绪) wait之前一般会进行检测这里由于无法很好的模拟场景就暂时不加ifpthread_cond_wait(pcond,pmtx);//默认该线程在执行的时候wait代码被执行当前线程会立即被阻塞cout name running ... endl;pthread_mutex_unlock(pmtx);} } void func2(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond) {while(true){pthread_mutex_lock(pmtx);pthread_cond_wait(pcond,pmtx);//默认该线程在执行的时候wait代码被执行当前线程会立即被阻塞cout name running ... endl;pthread_mutex_unlock(pmtx);} } void func3(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond) {while(true){pthread_mutex_lock(pmtx);pthread_cond_wait(pcond,pmtx);//默认该线程在执行的时候wait代码被执行当前线程会立即被阻塞cout name running ... endl;pthread_mutex_unlock(pmtx);} } void func4(const string name,pthread_mutex_t* pmtx, pthread_cond_t* pcond) {while(true){pthread_mutex_lock(pmtx);pthread_cond_wait(pcond,pmtx);//默认该线程在执行的时候wait代码被执行当前线程会立即被阻塞cout name running ... endl;pthread_mutex_unlock(pmtx);} }void* Entry(void* args) {ThreadData* td (ThreadData*)args;//td在每一个线程自己私有的栈空间保存td-_func(td-_name,td-_pmtx,td-_pcond);delete td;return nullptr; } int main() {pthread_mutex_t mtx;pthread_cond_t cond;pthread_mutex_init(mtx,nullptr);pthread_cond_init(cond,nullptr);pthread_t tids[PTHREAD_NUM];//定义四个线程的回调方法func_t funcs[PTHREAD_NUM] {func1,func2,func3,func4};for(int i 0; i PTHREAD_NUM; i){string name thread ;name to_string(i1);ThreadData* td new ThreadData(name,funcs[i],mtx,cond);pthread_create(tidsi,nullptr,Entry,(void*)td);}//这里为了方便演示pthread_cond_wait,在没有用signal或broadcast唤醒前一直处于阻塞状态sleep(5);//控制线程while(true){cout wake up thread run code ... endl;//pthread_cond_signal(cond);//唤醒一个线程pthread_cond_broadcast(cond);//唤醒全部线程sleep(1);}for(int i 0; i PTHREAD_NUM; i){pthread_join(tids[i],nullptr);}pthread_mutex_destroy(mtx);pthread_cond_destroy(cond);return 0; }
http://www.w-s-a.com/news/734/

相关文章:

  • 潮州网站seowordpress 调用置顶文章
  • 做带会员后台的网站用什么软件旅游网站建设资金请示
  • 商品网站怎么做wordpress 表情拉长
  • 商城网站设计费用网络公司怎样推广网站
  • 视频公司的网站设计工图网
  • 免费快速网站十八个免费的舆情网站