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

潍坊做网站的公司外贸推广方式都有哪些

潍坊做网站的公司,外贸推广方式都有哪些,广州推广广告,wordpress删除用户文章目录 前言一、锁1.定义一个锁变量2.pthread_mutex_init3.pthread_mutex_destroy4.pthread_mutex_lock/pthread_mutex_unlock5.静态变量锁和全局变量锁的初始化 二、问题描述及锁的运用三、RAII风格的锁 前言 临界资源: 在多个线程或进程间共享的资源. 临界区: 代码中访问临…

文章目录

  • 前言
  • 一、锁
    • 1.定义一个锁变量
    • 2.pthread_mutex_init
    • 3.pthread_mutex_destroy
    • 4.pthread_mutex_lock/pthread_mutex_unlock
    • 5.静态变量锁和全局变量锁的初始化
  • 二、问题描述及锁的运用
  • 三、RAII风格的锁


前言

临界资源: 在多个线程或进程间共享的资源.
临界区: 代码中访问临界资源的那部分代码区域.
多个线程同时访问共享数据, 其中至少一个线程进行了写操作, 且没有适当的同步机制来保护数据, 可能导致数据的不一致性, 也就是一种线程安全问题.

一、锁

多个线程同时访问共享数据, 其中至少一个线程进行了写操作, 且没有适当的同步机制来保护数据, 可能导致数据的不一致性, 对于这种问题, 可以通过加锁来解决, 加锁后, 只有申请到锁的线程才能进入临界区执行代码语句, 其他没有竞争到锁的线程会阻塞等待, 直到申请到锁的线程将锁释放, 接着各个线程再来竞争锁.
相当于被加锁的代码区域只能被各个线程串行执行.

1.定义一个锁变量

头文件: #include <pthread.h>

pthread_mutex_t mutex;

2.pthread_mutex_init

头文件: #include <pthread.h>
函数声明: int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

  • 返回值: 如果成功, 返回值为 0, 如果失败, 返回一个非零错误码.
  • mutex: 指向要初始化的互斥锁的指针.
  • attr: 设置互斥锁的属性, 一般传递 nullptr, 表示使用默认属性.

功能: 初始化锁.

示例代码:

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, nullptr);

3.pthread_mutex_destroy

头文件: #include <pthread.h>
函数声明: int pthread_mutex_destroy(pthread_mutex_t *mutex);

  • 返回值: 如果成功, 返回值为 0, 如果失败, 返回一个非零错误码.
  • mutex: 指向要释放的互斥锁的指针.

功能: 释放锁.

示例代码:

pthread_mutex_t mutex;
pthread_mutex_destroy(&mutex);

4.pthread_mutex_lock/pthread_mutex_unlock

头文件: #include <pthread.h>
函数声明: int pthread_mutex_lock(pthread_mutex_t *mutex); / int pthread_mutex_unlock(pthread_mutex_t *mutex);

  • 返回值: 如果成功, 返回值为 0, 如果失败, 返回一个非零错误码.
  • mutex: 指向已初始化的互斥锁的指针.

功能: 加锁/解锁.

示例代码:

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, nullptr);
pthread_mutex_lock(&mutex);
//...
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);

在 pthread_mutex_lock(&mutex); 和 pthread_mutex_unlock(&mutex); 之间的代码就是被加锁的代码, 只有申请到锁的线程才能进入执行, 释放锁后, 各个线程再重新竞争锁.

5.静态变量锁和全局变量锁的初始化

如果锁变量是 static 修饰的静态变量锁或者是声明在全局的锁, 可以直接通过宏进行初始化:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

二、问题描述及锁的运用

假设多个线程的入口函数为同一个, 代码如下:

#include <iostream>
#include <pthread.h>
using namespace std;void* Routine(void* arg)
{int cnt = 0;for(int i = 0; i < 3; ++i){printf("线程[%lld]中的cnt: %d, 地址为: 0x%x\n", pthread_self(), ++cnt, &cnt);}cout << endl;
}int main()
{pthread_t tids[3];for(int i = 0; i < 3; ++i){pthread_create(tids + i, nullptr, Routine, nullptr);}for(int i = 0; i < 3; ++i){pthread_join(tids[i], nullptr);}return 0;
}

可以看到, 在入口函数中, 存在一个变量 cnt, 那么多个线程的入口函数都是同一个, 每个线程都对该入口函数里的 cnt 进行累加操作, 是否会出现线程安全问题呢?

运行结果:
在这里插入图片描述
这里是不存在线程安全问题的, 因为每个线程在线程库中都存在自己的结构及数据上下文:
在这里插入图片描述
所以在入口函数中的变量等数据都是每个线程私有的一部分, 因此并不会有线程安全问题.

但是如果是全局变量或者被 static 修饰的变量, 被多个线程同时访问修改时就会存在线程安全问题, 假设一个场景: 三个线程进行"抢票", 即对全局变量 tickets 进行减减操作, 代码如下:

#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
using namespace std;int tickets = 30; //总票数void* Ticket(void* arg)
{while(1){//还有票if(tickets > 0){usleep(100000); //休眠0.1秒,模拟抢票前戏printf("线程 0x%x 抢到了一张票,还剩 %d 张票...\n", pthread_self(), --tickets);}else{break;}}return nullptr;
}int main()
{pthread_t tids[3];for(int i = 0; i < 3; ++i){pthread_create(tids + i, nullptr, Ticket, nullptr);}for(int i = 0; i < 3; ++i){pthread_join(tids[i], nullptr);}return 0;
}

运行结果:
在这里插入图片描述
可以看到, 在不加锁的情况下, tickets 直接被干到负数了, 原因就在于当 tickets 只剩 1 张时, 进行 if(tickets > 0) 判断时, 三个线程并行的执行了判断且进入了 if 语句内, 那 tickets 被干到负数也是必然的了.

通过加锁来规避这个问题, 代码修改如下:

#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
using namespace std;int tickets = 10000; //总票数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void* Ticket(void* arg)
{while(1){pthread_mutex_lock(&mutex);//还有票if(tickets > 0){usleep(50000); //休眠0.05秒,模拟抢票前戏printf("线程 0x%x 抢到了一张票,还剩 %d 张票...\n", pthread_self(), --tickets);pthread_mutex_unlock(&mutex);}else{pthread_mutex_unlock(&mutex);break;}}return nullptr;
}int main()
{pthread_t tids[3];for(int i = 0; i < 3; ++i){pthread_create(tids + i, nullptr, Ticket, nullptr);}for(int i = 0; i < 3; ++i){pthread_join(tids[i], nullptr);}pthread_mutex_destroy(&mutex);return 0;
}

需要注意的是 if 和 else 语句中都需要进行解锁, 如果只在 if 中解锁, 最后申请到锁但走了 else 语句的线程就并没有释放锁, 可能导致其他在等待锁资源的线程永远阻塞申请不到锁.

运行结果:
在这里插入图片描述

三、RAII风格的锁

虽然加锁, 解锁配套使用不难, 但毕竟是人写的, 难免可能出现加锁后忘了解锁, 而后导致死锁的情况, 所以通过 RAII 设计风格封装一下锁的使用, 可以有效避免这种问题.

示例代码:

#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
using namespace std;int tickets = 100; //总票数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;class LockGuard 
{
public://构造加锁LockGuard(pthread_mutex_t* m): _pmutex(m){pthread_mutex_lock(_pmutex);}//析构解锁~LockGuard (){pthread_mutex_unlock(_pmutex);}
public:pthread_mutex_t* _pmutex;
};void* Ticket(void* arg)
{while(1){usleep(100000);LockGuard lg(&mutex);//还有票if(tickets > 0){usleep(50000); //休眠0.05秒,模拟抢票前戏printf("线程 0x%x 抢到了一张票,还剩 %d 张票...\n", pthread_self(), --tickets);}else{break;}}return nullptr;
}int main()
{pthread_t tids[3];for(int i = 0; i < 3; ++i){pthread_create(tids + i, nullptr, Ticket, nullptr);}for(int i = 0; i < 3; ++i){pthread_join(tids[i], nullptr);}pthread_mutex_destroy(&mutex);return 0;
}

运行结果:
在这里插入图片描述
这样可以达到, 构造时加锁, 析构时解锁, 全自动化, 不必担心忘了解锁了.

http://www.dt0577.cn/news/26526.html

相关文章:

  • 网站 可以做无形资产吗关键词收录查询工具
  • 下载网站后怎么做的专门搜索知乎内容的搜索引擎
  • wordpress主题 点赞海淀区seo多少钱
  • 张家港网站设计制作学it一年的学费大概是多少
  • 吉安信息网百度网站优化
  • 做名片网站百度爱采购优化软件
  • 中国电商网站排行榜西安网站制作
  • 宣威做网站建设的公司互联网推广引流
  • 做价值投资有哪些网站网络游戏推广
  • 常德网站优化咨询电话网络广告的形式有哪些?
  • 应用商店下载2022最新版seo交流网
  • 网站空间排名点击软件怎样
  • 谁做的新闻网站比较好百度平台客服电话是多少
  • 大港油田建设官方网站适合seo的网站
  • 常用外贸b2b平台有哪些绍兴百度seo排名
  • 企业网站备案收费免费智能seo收录工具
  • 视频网站seo怎么做简单的个人主页网站制作
  • typecho和wordpress南昌seo排名优化
  • 网站返回首页怎么做100个成功营销案例
  • 如何查询一个网站的空间服务商seo自然优化排名
  • 比亚迪新能源汽车秦长春seo技术
  • 河北建设厅网站首页镇江seo快速排名
  • 网站优化的作业及意义房地产十大营销手段
  • 我国政府网站建设研究论文引擎优化seo是什么
  • 网站主页尺寸西安百度seo代理
  • 网页制作与设计书籍心得体会网站seo快速
  • 安装wordpress数据库连接时出错优化关键词怎么做
  • b2b批发网站大全dw如何制作网页
  • dw网站模板免费网上宣传广告怎么做
  • 做外贸没有网站需要环球网最新消息