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

论坛制作谷歌seo推广

论坛制作,谷歌seo推广,做门户网站源码,门户网站的区别知识回顾 在学习本篇内容前,我们需要先回顾一下几个概念。 临界资源:多线程执行流共享的资源就叫做临界资源 临界区:每个线程内部,访问临界资源的代码,就叫做临界区 互斥:任何时刻,互斥保证有…

知识回顾

在学习本篇内容前,我们需要先回顾一下几个概念。

临界资源:多线程执行流共享的资源就叫做临界资源

临界区:每个线程内部,访问临界资源的代码,就叫做临界区 

互斥:任何时刻,互斥保证有且只有⼀个执行流进入临界区,访问临界资源,通常对临界资源起保护作用

原子性(后面讨论如何实现):不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成

大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,变量 归属单个线程,其他线程无法获得这种变量。但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。此时如果多个线程并发操作共享变量,可能会有一些问题。因此,我们需要理解互斥与同步的原理并对共享资源在合适的时候“加锁”。

我们所保护的,并不是所谓的共享资源,而是称为临界区的代码。在临界区内,我们通过加锁只允许一个线程执行。

加锁一定不能大块代码地进行加锁,只要把临界区的一部分加锁即可。

一、不加锁会出现什么问题

这里我们写了一个利用线程进行抢票功能的代码(线程封装是作者自己写的这里直接拿来用,实际中直接调用pthread_create即可)

#include <iostream>
#include "mythread.hpp"
#include <vector>
using namespace ThreadModule;#define NUM 4
int ticket = 10000; // 共享资源
void Ticket()
{while (true){if (ticket > 0){usleep(1000);// 抢票printf("get ticket success ! ticketnum:%d\n", ticket--);}else{break;}}
}int main()
{// 构建线程对象std::vector<Thread> threads;for (int i = 0; i < NUM; i++){threads.emplace_back(Ticket);}// 启动线程for (auto &thread : threads){thread.Start();}// 等待for (auto &thread : threads){thread.Join();}
}

按道理来说票数为正就会一直抢,直到0所有进程就会退出抢票,但我们运行时发现,票数居然出现负数了?!这是为什么呢?

这就需要我们最上面的概念——原子性,在ticket--的过程中一共有三步:把ticket从内存放在CPU,CPU进行--,再放回内存,这是对于每一个线程的过程,但是在这个过程中,如果我们把数据放进CPU那么这个数据就对于线程是私有的了(本身的ticket是全局变量所以共享资源),他们完成第一步时,这时线程突然切换了,结果到下一个线程本来应该拿到比上个线程少一的ticket,但因为上一个还没有--所以拿到的值是一样的,然后当他们都进行--,就会出现为负数的原因。所以,--操作并不是原子性的,(if也不是)我们要加锁本质就是不让线程在完成这些操作的过程中被切换。

二、关于锁

1.锁长什么样

我们可以定义一个pthread_mutex_t类型(pthread库中提供的类型)的变量,这就是一把锁,第二个接口就是对锁进行初始化。但如果我们定义的锁是全局或静态的,就可以用最下面的宏进行初始化(这种锁就不需要destroy)。

2.怎么加锁与解锁

我们只需要把锁的地址传进来就行了。

所以现在上面的情况就可以解决了。

pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
int ticket = 10000; // 共享资源
void Ticket()
{while (true){pthread_mutex_lock(&lock);if (ticket > 0){usleep(1000);// 抢票printf("get ticket success ! ticketnum:%d\n", ticket--);pthread_mutex_unlock(&lock);}else{pthread_mutex_unlock(&lock);break;}}
}

只要线程启动就要保证原子性,完成后进行解锁。

锁作为全局变量,保护着全局变量的资源(临界资源),可是谁来保证锁的安全,锁只需要保证原子性即可。

线程在申请锁的时候,其他线程要进行阻塞等待!线程在访问临界区代码时,是可以切换的,但在加锁的线程被切走的时候,其他线程是无法进来访问临界区的,该线程要么不做,要么做完!这对于其他线程就保证了原子性。

其实,锁这个概念就是线程互斥,就是为了让线程在完成任务的过程中不让其他线程“加入”等自己完成后再让他们执行。

三、锁的封装

这里无非就是利用lock和unlock所以直接上代码

#pragma once
#include <iostream>namespace LockModule
{class Mutex{public:Mutex(const Mutex&)=delete;//需要保证多线程用一把锁,不允许赋值和拷贝const Mutex& operator =(const Mutex&)=delete;Mutex(){int n=::pthread_mutex_init(&_lock,nullptr);(void)n;}~Mutex(){int n=::pthread_mutex_destroy(&_lock);(void)n;}void Lock(){int n=::pthread_mutex_lock(&_lock);(void)n;}void Unlock(){int n=::pthread_mutex_unlock(&_lock);(void)n;}private:pthread_mutex_t _lock;};class LockGuard{public:LockGuard(Mutex&mtx):_mtx(mtx){_mtx.Lock();}~LockGuard(){_mtx.Unlock();}private:Mutex& _mtx;};
}

封装lockguard类是通过构造和析构直接实现锁的初始化和回收

http://www.cadmedia.cn/news/2436.html

相关文章:

  • 什么网站可以做注册任务谷歌搜索引擎google
  • 网站推广方法及特点产品推广方案ppt
  • 如何进行网络销售北京企业网站seo平台
  • 内部网站管理办法seo技术培训茂名
  • 张家口网站建设工作室今日新闻头条内容
  • 江西建设厅网站松松软文平台
  • 上海网站托管最新足球新闻头条
  • 深圳网站设计兴田德润放心深圳优化公司排名
  • 公司一般有哪些部门北京做的好的seo公司
  • b2c网站的服务内容bt种子搜索神器
  • b2b网站盈利模式厦门网站外包
  • 网站建设基本步骤怎么让付费网站免费
  • 旅游网站网页设计模板代码推广项目
  • 自贡普通网站建设费用写文案接单平台
  • 网站外包多少人做站长工具seo综合查询官网
  • 陶瓷刀具网站策划书seo推广外包企业
  • 网站优化网站建设公司seo和sem是什么意思
  • 学动漫去哪个学校关键词排名优化顾问
  • 网站建设好做吗培训网站推广
  • 作网站短视频搜索优化
  • 广东网站建设开发seo优化课程
  • 日照建设企业网站厦门seo外包平台
  • 江苏省建筑人才网辽阳网站seo
  • 做网站的 需要续费维护费吗百度手机浏览器下载
  • 石家庄网站模板建站五年级下册数学优化设计答案
  • 深圳网站建设收费标准网络优化行业的发展前景
  • 深圳哪个网站建设公司好企业网站优化公司
  • 网站建设人员要与客户谈什么站长之家app下载
  • 日照网站建设不全今日最新消息新闻报道
  • 政府网站建设工作推进会武汉最新消息今天