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

网站平台建设合同模板wordpress pc 和手机

网站平台建设合同模板,wordpress pc 和手机,企业为什么要做建站,网站友链外链线程互斥 线程互斥#xff1a; 任何时刻#xff0c;保证只有一个执行流进入临界区访问临界资源#xff0c;通常对临界资源起到保护作用 相关概念 临界资源#xff1a; 一次仅允许一个进程使用的共享资源临界区#xff1a; 每个线程内部#xff0c;访问临界资源的代码 任何时刻保证只有一个执行流进入临界区访问临界资源通常对临界资源起到保护作用 相关概念 临界资源 一次仅允许一个进程使用的共享资源临界区 每个线程内部访问临界资源的代码就叫做临界区原子性 不会被任何调度机制打断的操作该操作只有两态无中间态即使被打断也不会受影响要么完成要么未完成 互斥量mutex 概念 多个线程对一个共享变量进行操控时会引发数据不一致的问题。此时就引入了互斥量也叫互斥锁的概念来保证共享数据操作的完整性。在被加锁的任一时刻临界区的代码只能被一个线程访问。 为了更好的阐述这个概念这里用一个抢票代码去演示 #include iostream #include vector #include cstdio #include cstring #include string #include unistd.h #include cassert #include pthread.h int ticket1000; void* getTicket(void* args) {long id(long) args;while(1){if(ticket0){usleep(1000);--ticket;printf(thread %ld get a ticket,the number is %d\n,id,ticket);}else{break;}} } int main() {//创建五个线程pthread_t t1[5];for(int i0;i5;i){pthread_create(t1[i],nullptr,getTicket,(void*)i);}//主线程在阻塞等待for(int i0;i5;i){pthread_join(t1[i],nullptr);}return 0; }运行结果如下 我们发现票到负数了还会继续执行 原因如下 if 语句判断条件为真以后代码可以并发的切换到其他线程usleep 这个过程中ticket还没有进行--的操作有很多线程会进入if条件–-ticket 操作本身就不是一个原子操作ticket有三条汇编指令如下 movl ticket(%rip), %eax # 把ticket的值(内存)加载到eax寄存器中 subl $1, %eax # 把eax寄存器中的值减1 movl %eax, ticket(%rip) # 把eax寄存器中的值赋给ticket变量有可能在你执行到第二条汇编的时候还没来得及拷贝给内存就别切换走了就会导致减到负数因为别的线程在读取的时候内存中的ticket还是1 如何解决上述问题 代码必须要有互斥行为当代码进入临界区执行时不允许其他线程进入该临界区。如果多个线程同时要求执行临界区的代码并且临界区没有线程在执行那么只能允许一个线程进入该临界区。如果线程不在临界区中执行那么该线程不能阻止其他线程进入临界区。 在临界区内线程只能串行执行在临界区外线程可以并发执行 互斥量的接口 互斥量其实就是一把锁是一个类型为pthread_mutex_t的变量使用前需要进行初始化操作使用完之后需要对锁资源进行释放 初始化互斥量: 全局锁或静态锁pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER 局部锁 int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);参数 restrict mutex要初始化的锁 restrict attr不关心置空 返回值 成功返回0失败返回错误码 注意 互斥量处于未锁状态该函数会将互斥量锁定同时返回成功 函数调用时其他线程已经锁定互斥量或者存在其他线程同时申请互斥量但没有竞争到互斥量那么pthread_ lock调用会陷入阻塞(执行流被挂起)等待互斥量解锁再去竞争锁 ⭐ 如果在全局区或者定义的静态变量只需要写成pthread_mutex_t mutex PTHREAD_MUTEX_INITIALIZER 不需要写初始化和销毁 加锁 int pthread_mutex_lock(pthread_mutex_t *mutex);参数 mutex要加的锁 返回值 成功返回0失败返回错误码 解锁 int pthread_mutex_unlock(pthread_mutex_t *mutex);参数 mutex要解的锁 返回值 成功返回0失败返回错误码 销毁互斥量 int pthread_mutex_destroy(pthread_mutex_t *mutex);参数 mutex要销毁锁 返回值 成功返回0失败返回错误码 注意 不要销毁一个已经加锁的互斥量已经销毁的互斥量要确保后面不会有线程再尝试加锁加锁的粒度要够小 用以上的方法再需要的地方进行加锁 #include iostream #include vector #include cstdio #include cstring #include string #include unistd.h #include cassert #include pthread.h using namespace std; int ticket1000; class ThreadData { public:ThreadData(const string threadname,pthread_mutex_t* mutex):thread_name(threadname),mutex_p(mutex){}string thread_name;pthread_mutex_t* mutex_p; }; //创建并初始化 //全局的锁这样写可以不用初始化和销毁 // pthread_mutex_t mutexPTHREAD_ MUTEX_ INITIALIZER; void* getTicket(void* args) {ThreadData *td static_castThreadData *(args);// ThreadData* td(ThreadData*) args;while(1){//加锁pthread_mutex_lock(td-mutex_p);if(ticket0){usleep(1000);cout td-thread_name tickets is ticket endl;--ticket;//解锁pthread_mutex_unlock(td-mutex_p);}else{//解锁pthread_mutex_unlock(td-mutex_p);break;}//抢完票就完了吗需要形成订单给用户//这里如果不休息会一直是第4个线程在跑原因是锁只规定互斥访问没有规定必须让谁优先执行//锁就是真是的让多个执行流进行竞争的结果usleep(1000);} }int main() {//创建五个线程pthread_t t1[5];pthread_mutex_t lock;pthread_mutex_init(lock,nullptr);for(int i0;i5;i){char buffer[64];snprintf(buffer,sizeof(buffer),%s%d,thread ,i1);//锁用同一把ThreadData* tdnew ThreadData(buffer,lock);pthread_create(t1[i],nullptr,getTicket,td);}for(int i0;i5;i){pthread_join(t1[i],nullptr);}pthread_mutex_destroy(lock);return 0; }运行结果如下 这里运行会变慢因为加锁以后是串行执行 如何看待锁 锁本身就是一个共享资源全局变量是要被保护的锁用来保护全局资源锁本身也是全局资源所以加锁的过程必须是安全的加锁的过程是**原子的锁如果申请成功继续向后执行**如果暂时没有申请成功执行流会阻塞 如果锁申请成功进入临界资源正在访问临界资源其他线程正在做什么 阻塞等待 如果锁申请成功进入临界资源正在访问临界资源我可以被切换吗 可以当持有线程的锁被切走其他线程依旧无法申请锁成功也无法向后执行直到我释放这个锁 互斥量的原理 大多数体系结构都提供了swap或exchange指令该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令保证了原子性 下面是lock和unlock的伪代码 lock:movb $0, %a1 # 把0值放进寄存器a1里xchgb %a1, mutex # 交换a1寄存器的内容和锁的值无线程使用锁时metux的值为1 if (%a1 0)return 0; # 得到锁else挂起等待;goto lock; unlock:movb $1 mutex #把1赋给锁 唤醒等待的线程;return 0;下图展示了如何实现 解锁的伪代码步骤只有有锁的线程才可以执行到这段代码 把mutex的值改为1唤醒等待锁的线程 封装锁 Mutex.hpp #pragma once#include iostream #include pthread.hclass Mutex { public:Mutex(pthread_mutex_t *lock_p nullptr): lock_p_(lock_p){}void lock(){if(lock_p_) pthread_mutex_lock(lock_p_);}void unlock(){if(lock_p_) pthread_mutex_unlock(lock_p_);}~Mutex(){} private:pthread_mutex_t *lock_p_; };class LockGuard { public:LockGuard(pthread_mutex_t *mutex): mutex_(mutex){mutex_.lock(); //在构造函数中进行加锁}~LockGuard(){mutex_.unlock(); //在析构函数中进行解锁} private:Mutex mutex_; };test.cpp #include iostream #include vector #include cstdio #include cstring #include string #include unistd.h #include pthread.h #include memory #include cassert#include Mutex.hpp// 共享资源 火车票 int tickets 10000; pthread_mutex_t lock PTHREAD_MUTEX_INITIALIZER; void *getTicket(void *args) {long long username (long long)args;while (true){{//出了作用域会销毁LockGuard lockguard(lock); // RAII风格的加锁if (tickets 0){usleep(1254); std::cout username 正在进行抢票: tickets std::endl;tickets--;}else{break;}}usleep(1000); }return nullptr; } int main() {#define NUM 4pthread_t t1[5];for(int i0;i5;i){pthread_create(t1[i],nullptr,getTicket,(void*)i);}//主线程保持运行for(int i0;i5;i){pthread_join(t1[i],nullptr);}return 0; }线程安全和可重入 概念 线程安全 多个线程并发同一段代码时不会出现不同的结果。常见对全局变量或者静态变量进行操作并且没有锁保护的情况下会出现该问题。 重入 同一个函数被不同的执行流调用当前一个流程还没有执行完就有其他的执行流再次进入我们称之为重入。一个函数在重入的情况下运行结果不会出现任何不同或者任何问题则该函数被称为可重入函数否则是不可重入函数。 常见的线程安全的情况 每个线程对全局变量或者静态变量只有读取的权限而没有写入的权限一般来说这些线程是安全的类或者接口对于线程来说都是原子操作多个线程之间的切换不会导致该接口的执行结果存在二义性 常见的线程不安全的情况 不保护共享变量的函数函数状态随着被调用状态发生变化的函数返回指向静态变量指针的函数调用线程不安全函数的函数 常见可重入的情况 不使用全局变量或静态变量不使用用malloc或者new开辟出的空间不调用不可重入函数不返回静态或全局数据所有数据都有函数的调用者提供使用本地数据或者通过制作全局数据的本地拷贝来保护全局数据 常见不可重入的情况 调用了malloc/free函数因为malloc函数是用全局链表来管理堆的调用了标准I/O库函数标准I/O库的很多实现都以不可重入的方式使用全局数据结构可重入函数体内使用了静态的数据结构 区别与联系 区别 函数是可重入的那就是线程安全的函数是不可重入的那就不能由多个线程使用有可能引发线程安全问题如果一个函数中有全局变量那么这个函数既不是线程安全也不是可重入的 联系 可重入函数是线程安全函数的一种线程安全不一定是可重入的不一定发生线程安全问题而可重入函数则一定是线程安全的。如果将对临界资源的访问加上锁则这个函数是线程安全的但如果这个重入函数若锁还未释放则会产生死锁因此是不可重入的。 死锁 概念 死锁是指两个或两个以上的进程在执行过程中由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁这些永远在互相等待的进程称为死锁进程。 死锁产生的四个必要条件 互斥条件一个资源每次只能被一个执行流使用请求与保持条件一个执行流因请求资源而阻塞时对已获得的资源保持不放不剥夺条件:一个执行流已获得的资源在未使用完之前不能强行剥夺循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系 所谓的必要条件是都要满足才能形成死锁只要有一个不满足就不是死锁 避免死锁 破坏死锁的四个条件上面分别对应的是1.不使用锁 2.让一个执行流放开资源 3. 让一个个执行流剥夺一个执行流的资源 4. 调整申请资源的顺序假设顺序要一致避免锁未释放的场景资源一次性分配 避免死锁算法 银行家算法为了防止银行家资金无法周转而倒闭对每一笔贷款必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题系统中有限的资源要供多个进程使用必须保证得到的资源的进程能在有限的时间内归还资源以供其他进程使用资源。死锁检测法
http://www.dnsts.com.cn/news/204362.html

相关文章:

  • 耒阳网站建设wordpress 自动采集
  • 行唐县做网站电话外贸收款平台有哪些
  • 图片 网站源码 采集免费网站建设哪个好
  • seo网站推广是什么app 开发 wordpress
  • 杨浦做网站wordpress所有函数
  • 天津专门做网站的公司福田响应式网站建设服务
  • 温岭 网站建设清远市企业网站seo联系方式
  • 学校网站素材重写路由 wordpress
  • 网站开发程序员的工资是多少wordpress 好 免费主题
  • 论文中小企业的网站建设做旅行路线的网站
  • 专门做包装的网站网站开发语言占有率
  • 新网站怎样做优化网站导航栏 字体
  • 网站如何查看浏览量商业网站的建设
  • 怎样进行网站板块建设企业信息服务平台官网
  • 深圳外贸网站建设crm系统是什么
  • 自适应营销网站龙海做网站费用
  • 昆山市建设局网站6软件外包上市公司
  • 网站行高酷炫网站源码
  • 做外贸公司 网站东莞企业网站哪家好
  • 进入网站后台ftp空间后怎样上传wordpress自动封面
  • 如何申请域名创建一个网站济宁网站建设制作设计
  • 原江苏省建设厅网站dw做网站时怎么改为绝对路径
  • 《网站开发技术》模板id导入不了wordpress
  • 网站资讯建设企业运营模式有哪些
  • asp语言的网站建设最新上线的手游
  • iis配置网站开发环境wordpress lover
  • 招聘网站可以同时做两份简历吗6joomla wordpress drupal
  • 广州网站建设哪家便宜石家庄住房和城乡建设厅官方网站
  • 南宁网站建设清单人力资源外包服务公司
  • 手机上怎么做自己的网站网站设计公司怎么样