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

企业建网站公司多少钱互联网创业项目怎么做

企业建网站公司多少钱,互联网创业项目怎么做,深圳社保个人网页登录,小组做数据库网站目录 前言:基于多线程不安全并行抢票 一、线程互斥锁 mutex 1.1 加锁解锁处理多线程并发 1.2 如何看待锁 1.3 如何理解加锁解锁的本质 1.4 CRAII方格设计封装锁 前言:基于线程安全的不合理竞争资源 二、线程同步 1.1 线程同步处理抢票 1.2 如何…

目录

前言:基于多线程不安全并行抢票

一、线程互斥锁 mutex

1.1 加锁解锁处理多线程并发

 1.2 如何看待锁

1.3 如何理解加锁解锁的本质

1.4 C++RAII方格设计封装锁

前言:基于线程安全的不合理竞争资源

二、线程同步

1.1 线程同步处理抢票

1.2 如何理解"条件变量"

1.3 如何理解条件变量函数需要传锁参数


前言:基于多线程不安全并行抢票

#include<iostream>
#include<pthread.h>
#include<unistd.h>
#define NUM 10
using namespace std;
int global_ticket = 10000;void* GetTicket(void* args)
{char* pc =(char*)args;while(global_ticket > 0){usleep(123);cout << pc <<" ticket= " << global_ticket--<<endl;}delete pc;
}int main()
{for(int i=0;i<NUM;i++){char* pc = new char[64];pthread_t tid;snprintf(pc,128,"thread %d get a ticket",i+1);pthread_create(&tid,nullptr,GetTicket,pc);}while(true);return 0;
}

发现结果和我们代码的预想不一样,出现了票已经售完却仍抢票的现象!

为什么会出现这种现象? 原来Linux线程是轻量级进程,是CPU调度的基本单位,所以每个线程在CPU中都有自己的时间片,所以线程会在CPU上不断的切换,这样有可能某个线程在运行函数过程中突然被截胡了!然后再轮到它的时候继续运行!那结合本次抢票逻辑,可能某个线程首先while条件满足了拥有了抢票资格,但是没有开始抢票就被截胡了,下次回来后它仍拥有资格拿到一张票,可是之前票已经被抢完了!所以他其实没有资格了,但是因为不安全访问全局变量,使得它可以继续拿到票!

这样因为线程的特性原因使得我们无法安全的访问一个全局共享变量!所以我们要使线程互斥访问该变量,当某一个线程访问的时候,其他线程无法干预截胡,该线程必须将自己的代码逻辑执行完或者不执行(要么不做,做就必须完成!) 这就叫线程的互斥!那些代码区域称作为临界区!


一、线程互斥锁 mutex

1.1 加锁解锁处理多线程并发


#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<string>
#include<vector>
using namespace std;int tickets = 10000;class Thread_data
{
public:string name_;pthread_mutex_t* mutex_;
};void* pthread_route(void* args)
{Thread_data* pt = static_cast<Thread_data*>(args);while(true){//加锁pthread_mutex_lock(pt->mutex_);if(tickets > 0){cout << pt->name_<<"get a ticket, tickets = "<<--tickets <<endl;//解锁pthread_mutex_unlock(pt->mutex_);//!!!抢完票后的操作 如果没有这个步骤,该线程会一直占用CPU执行抢票逻辑!usleep(1234);}else{//注意这个逻辑里也要解锁!pthread_mutex_unlock(pt->mutex_);break;}}delete pt;
}#define NUM 5
int main()
{vector<pthread_t> vp(NUM); char buffer[64];//锁初始化//1.锁类型 + 初始化函数//2.全局变量 pthread_mutex_t mutex =宏(PTHREAD_MUTEX_INITIALIZER)pthread_mutex_t mutex;pthread_mutex_init(&mutex,nullptr);for(int i=0;i<NUM;i++){pthread_t tid;snprintf(buffer,sizeof(buffer),"thread %d ",i+1);Thread_data* pt = new Thread_data();pt->mutex_ = &mutex;pt->name_ = buffer;pthread_create(&(vp[i]),nullptr,pthread_route,pt);}for(const auto& tid : vp){pthread_join(tid,nullptr);}return 0;
}

现在结果看到不会出现票数为负数的情况,锁保护了我们的共享资源tickets! 


 1.2 如何看待锁

a.锁本身被线程共享,是一个共享资源,锁保护全局变量,锁本身也需要被保护

b.加锁和解锁的过程必须是安全的,也就说加锁的过程必须是原子性的!

c.如果锁申请成功,就继续向后执行,如果不成功则执行流阻塞!

d.谁持有锁,谁进入临界区!

1.3 如何理解加锁解锁的本质

首先理解这个过程我们首先要明确关于CPU的一个知识就是寄存器:

寄存器只有一套,但寄存器被线程所共享,寄存器存储的内容只被当前线程所拥有!

加锁的过程:

① 将内存中的线程变量al的值0放入CPU的寄存器内

② 然后将寄存器内的0与内存变量mutex值交换,其中mutex的为1,这样mutex = 0

③ 最后通过判断al在寄存器的值来判断是否能申请锁成功!>0 成功 else 不成功

此时当某个线程完成了前面两个步骤,其他线程申请锁时将等于0的mutex与al交换,al依旧是0所以他无法申请锁!这样就可以保证只有一个线程申请到锁!

解锁的过程:就是把寄存器al的1存入mutex中即可!

这里swap过程很重要,它是一条汇编完成!其本质是将共享变量放入到我们的上下文中!


1.4 C++RAII方格设计封装锁

//mutex.hpp
#include<iostream>
#include<pthread.h>class 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_);}
private:pthread_mutex_t* lock_p_;
};class LockGuard
{
public:LockGuard(pthread_mutex_t* mutex):mutex_(mutex){mutex_.lock();}~LockGuard(){mutex_.unlock();}
private:Mutex mutex_;
};

💡该封装利用局部类变量的构造析构随着作用域自动调用使得加锁解锁自动调用! 


前言:基于线程安全的不合理竞争资源

#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<string>
#include<vector>
#include"mutex.hpp"
using namespace std;int tickets = 10000;class Thread_data
{
public:string name_;pthread_mutex_t* mutex_;
};void* pthread_route(void* args)
{Thread_data* pt = static_cast<Thread_data*>(args);while(true){//加锁//pthread_mutex_lock(pt->mutex_);LockGuard lock(pt->mutex_);if(tickets > 0){cout << pt->name_<<"get a ticket, tickets = "<<--tickets <<endl;//解锁//pthread_mutex_unlock(pt->mutex_);//!!!抢完票后的操作 如果没有这个步骤,该线程会一直占用CPU执行抢票逻辑!}else{//注意这个逻辑里也要解锁!//pthread_mutex_unlock(pt->mutex_);break;}usleep(1000);}delete pt;
}#define NUM 5
int main()
{vector<pthread_t> vp(NUM); char buffer[64];//锁初始化//1.锁类型 + 初始化函数//2.全局变量 pthread_mutex_t mutex =宏(PTHREAD_MUTEX_INITIALIZER)pthread_mutex_t mutex;pthread_mutex_init(&mutex,nullptr);for(int i=0;i<NUM;i++){pthread_t tid;snprintf(buffer,sizeof(buffer),"thread %d ",i+1);Thread_data* pt = new Thread_data();pt->mutex_ = &mutex;pt->name_ = buffer;pthread_create(&(vp[i]),nullptr,pthread_route,pt);}for(const auto& tid : vp){pthread_join(tid,nullptr);}return 0;
}

 可以肯定的是线程资源是安全的了,但是却是一个线程在疯狂抢票,这样的行为不是错误的,但不合理!我们需要每个线程都有机会,所以引入线程同步,利用同步"信号"与等待队列来实现线程公平的竞争!


二、线程同步

1.1 线程同步处理抢票


#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
using namespace std;int tickets = 100;//初始化锁和条件变量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;void *pthread_route(void *args)
{string name = (char *)args;while (true){//加锁pthread_mutex_lock(&mutex);//条件等待信号唤醒pthread_cond_wait(&cond, &mutex);if (tickets > 0)cout << name << "get a ticket, tickets = " << --tickets << endl;pthread_mutex_unlock(&mutex);}
}int main()
{pthread_t tid1, tid2, tid3;pthread_create(&tid1, nullptr, pthread_route, (void *)"thread 1 ");pthread_create(&tid2, nullptr, pthread_route, (void *)"thread 2 ");pthread_create(&tid3, nullptr, pthread_route, (void *)"thread 3 ");// 主线程负责每隔一秒信号唤醒条件变量while (true){sleep(1);pthread_cond_signal(&cond);cout << "main wake up a thread ..." << endl;}pthread_join(tid1, nullptr);pthread_join(tid2, nullptr);pthread_join(tid3, nullptr);return 0;
}


 1.2 如何理解"条件变量"

首先明确一下整个代码逻辑:
a.先加锁,保护临界资源

b.条件等待,等待条件满足信号唤醒,否则阻塞!

c.解锁

当线程条件阻塞,会被放入条件队列中等待!当有信号唤醒的时候,从队列中一个一个得出!

1.3 如何理解条件变量函数需要传锁参数

因为等待队列被线程共享,为了保证线程入队列安全,所以需要加锁保护线程安全! 

http://www.hyszgw.com/news/53066.html

相关文章:

  • 江津网站建设效果好不好网站做任务包括什么
  • 化妆品购物网站模板返利网app网站开发
  • 网站开发感想长沙网页设计公司哪家好
  • 网站每年费用ps软件入门教程
  • 丰台建站推广哈尔滨专业网站建设公司
  • 网站开发技术简介dw重庆电商网站建设费用
  • 怎么直接做免费网站建设网站加盟
  • 柳州市住房和城乡建设部网站个人电脑可以做网站服务器
  • 电商网站建设合同扬中信息港
  • 山东川畅信息技术有限公司网站建设wordpress 证书风险
  • 泰州网站建设方案开发郑州比较好的设计公司
  • 网站5g空间推广公司网站
  • 郑州制作网站哪家好湖南响应式网站哪家好
  • 兰溪城市建设规划网站wordpress购买按钮
  • 网站怎么开启gzip蓬莱做网站那家好
  • 网站开发系统有哪些开发方案怎么做算命网站
  • 网站默认网站名推广方案有哪些
  • 塘沽网站建设wordpress多语言内容添加
  • 手机网站永久免费制作做网站必须得ipc
  • 怀化网站制作大学生做网站兼职
  • 推荐个在广州做网站的找外贸客户的联系方式软件
  • 海宁网站制作山西省住房与城乡建设厅网站
  • 赣州做网站wordpress建站用模板的弊端
  • 网站登记备案表俄罗斯最新消息今天新闻
  • 网站备案注销 万网品牌形象设计
  • 中英文免费网站建设软考5个高级中哪个好考
  • 网站显示危险网站天元建设集团有限公司新闻
  • 北京建站者公司互联网网站模板
  • 莆田网站建设莆田管理系统软件开发
  • 黔西南州做网站徐州企业建站模板