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

电商网站开发需求文档网站维护费用一般多少钱

电商网站开发需求文档,网站维护费用一般多少钱,福清网站建设,我国的b2b电子商务平台Linux线程安全 Linux线程安全详解Linux线程互斥进程线程间的互斥相关背景概念互斥量mutex互斥量的接口互斥量实现原理探究 可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见的不可重入的情况常见的可重入的情况可重入与线程安全联系可重入与线程安全区别 常…

Linux线程安全

  • Linux线程安全详解
    • Linux线程互斥
      • 进程线程间的互斥相关背景概念
      • 互斥量mutex
      • 互斥量的接口
      • 互斥量实现原理探究
    • 可重入VS线程安全
      • 概念
      • 常见的线程不安全的情况
      • 常见的线程安全的情况
      • 常见的不可重入的情况
      • 常见的可重入的情况
      • 可重入与线程安全联系
      • 可重入与线程安全区别
    • 常见锁概念
      • 死锁
      • 死锁的四个必要条件
      • 避免死锁
    • Linux线程同步
      • 同步概念与竞态条件
      • 条件变量
      • 条件变量函数
      • 为什么pthread_cond_wait需要互斥量
      • 条件变量使用规范
    • 总结


Linux线程安全详解

Linux线程互斥

进程线程间的互斥相关背景概念

  • 临界资源:多线程共享的资源,如全局变量。
  • 临界区:访问临界资源的代码段。
  • 互斥:确保同一时刻只有一个线程进入临界区,保护临界资源。
  • 原子性:操作不可中断,要么完成要么未完成。

进程与线程对比

  • 进程间通信需创建第三方资源(如管道、共享内存),这些资源即临界资源,访问代码为临界区。
  • 线程共享进程的大部分资源(如全局变量),无需额外创建资源即可通信。

示例:线程间通信

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int count = 0;
void* Routine(void* arg) {while (1) {count++;sleep(1);}pthread_exit((void*)0);
}
int main() {pthread_t tid;pthread_create(&tid, NULL, Routine, NULL);while (1) {printf("count: %d\n", count);sleep(1);}pthread_join(tid, NULL);return 0;
}
  • count 是临界资源,被主线程和新线程共享。
  • count++printf 是临界区。

互斥与原子性问题
多线程并发操作临界资源可能导致数据不一致。例如抢票系统:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int tickets = 1000;
void* TicketGrabbing(void* arg) {const char* name = (char*)arg;while (1) {if (tickets > 0) {usleep(10000); // 模拟业务耗时printf("[%s] get a ticket, left: %d\n", name, --tickets);} else {break;}}printf("%s quit!\n", name);pthread_exit((void*)0);
}
int main() {pthread_t t1, t2, t3, t4;pthread_create(&t1, NULL, TicketGrabbing, "thread 1");pthread_create(&t2, NULL, TicketGrabbing, "thread 2");pthread_create(&t3, NULL, TicketGrabbing, "thread 3");pthread_create(&t4, NULL, TicketGrabbing, "thread 4");pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_join(t4, NULL);return 0;
}

运行结果可能出现负票数,原因:

  1. if (tickets > 0) 判断后线程可能切换。
  2. usleep 期间其他线程可进入临界区。
  3. --tickets 非原子操作,分为加载(load)、更新(update)、存储(store)三步,可能被打断。

互斥量mutex

互斥量(mutex)是Linux提供的锁机制,解决线程间的互斥问题,要求:

  1. 同一时刻只有一个线程进入临界区。
  2. 无线程在临界区时,允许多线程竞争进入。
  3. 线程不在临界区时不得阻止其他线程进入。

互斥量的接口

  • 初始化
    int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
    
    • 动态分配:pthread_mutex_init(&mutex, NULL);
    • 静态分配:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  • 销毁
    int pthread_mutex_destroy(pthread_mutex_t *mutex);
    
    • 注意:已加锁的互斥量不可销毁。
  • 加锁
    int pthread_mutex_lock(pthread_mutex_t *mutex);
    
    • 未锁:加锁成功。
    • 已锁:阻塞等待。
  • 解锁
    int pthread_mutex_unlock(pthread_mutex_t *mutex);
    

抢票系统改进

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int tickets = 1000;
pthread_mutex_t mutex;
void* TicketGrabbing(void* arg) {const char* name = (char*)arg;while (1) {pthread_mutex_lock(&mutex);if (tickets > 0) {usleep(100);printf("[%s] get a ticket, left: %d\n", name, --tickets);pthread_mutex_unlock(&mutex);} else {pthread_mutex_unlock(&mutex);break;}}printf("%s quit!\n", name);pthread_exit((void*)0);
}
int main() {pthread_mutex_init(&mutex, NULL);pthread_t t1, t2, t3, t4;pthread_create(&t1, NULL, TicketGrabbing, "thread 1");pthread_create(&t2, NULL, TicketGrabbing, "thread 2");pthread_create(&t3, NULL, TicketGrabbing, "thread 3");pthread_create(&t4, NULL, TicketGrabbing, "thread 4");pthread_join(t1, NULL);pthread_join(t2, NULL);pthread_join(t3, NULL);pthread_join(t4, NULL);pthread_mutex_destroy(&mutex);return 0;
}
  • 加锁后票数不再出现负值。
  • 注意:加锁降低并行性,需合理选择加锁范围。

互斥量实现原理探究

  • 原子性:加锁后,临界区操作对其他线程表现为原子性(要么未开始,要么已完成)。
  • 线程切换:临界区内可能切换,但锁未释放,其他线程无法进入。
  • 锁的保护:锁本身是临界资源,需保证申请过程原子性。
  • 实现机制:使用 swap/exchange 指令(单指令原子性)。
    • 伪代码
      • 加锁:xchgb 交换寄存器(清0)与 mutex(初始1),成功得1,失败得0。
      • 解锁:mutex 置1,唤醒等待线程。
    • 原理:总线周期独占,确保多核环境下原子性。

可重入VS线程安全

概念

  • 线程安全:多线程并发执行同一代码,结果一致。
  • 可重入:函数被多执行流调用,前一流未结束,后一流进入,结果无误。

常见的线程不安全的情况

  • 无锁保护的共享变量操作。
  • 函数状态随调用改变(如静态变量)。
  • 返回静态变量指针。
  • 调用线程不安全函数。

常见的线程安全的情况

  • 只读全局/静态变量。
  • 接口操作原子性。
  • 线程切换不影响结果。

常见的不可重入的情况

  • 调用 malloc/free(全局堆链表)。
  • 使用标准I/O(全局数据结构)。
  • 函数体内依赖静态数据。

常见的可重入的情况

  • 不使用全局/静态变量。
  • 不调用 malloc/new
  • 不调用不可重入函数。
  • 数据由调用者提供或局部拷贝。

可重入与线程安全联系

  • 可重入函数一定是线程安全的。
  • 不可重入函数多线程使用可能不安全。
  • 有全局变量的函数通常既不可重入也不安全。

可重入与线程安全区别

  • 可重入是线程安全的一种。
  • 加锁可使函数线程安全,但若锁未释放则不可重入。

常见锁概念

死锁

死锁是多线程互相等待对方释放资源,导致永久阻塞。

  • 单线程死锁:同一线程多次申请同一锁。

    #include <stdio.h>
    #include <pthread.h>
    pthread_mutex_t mutex;
    void* Routine(void* arg) {pthread_mutex_lock(&mutex);pthread_mutex_lock(&mutex); // 死锁pthread_exit((void*)0);
    }
    int main() {pthread_mutex_init(&mutex, NULL);pthread_t tid;pthread_create(&tid, NULL, Routine, NULL);pthread_join(tid, NULL);pthread_mutex_destroy(&mutex);return 0;
    }
    
    • 状态:Sl+(锁阻塞)。
  • 阻塞原理

    • 进程等待资源时,从运行队列移至资源等待队列。
    • 资源就绪后,唤醒并移回运行队列。

死锁的四个必要条件

  1. 互斥:资源独占。
  2. 请求与保持:持有资源并请求新资源。
  3. 不剥夺:资源不可强夺。
  4. 循环等待:线程间形成等待环。

避免死锁

  • 破坏任一必要条件。
  • 统一加锁顺序。
  • 避免未释放锁。
  • 一次性分配资源。
  • 使用死锁检测或银行家算法。

Linux线程同步

同步概念与竞态条件

  • 同步:在数据安全前提下,按特定顺序访问临界资源,避免饥饿。
  • 竞态条件:时序问题导致程序异常。
  • 问题:单纯加锁可能导致强竞争力线程垄断资源,其他线程饥饿。

条件变量

条件变量描述资源就绪状态,配合互斥锁实现同步:

  • 等待:线程挂起等待条件满足。
  • 唤醒:另一线程使条件满足并通知。

条件变量函数

  • 初始化
    int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    
    • 静态:pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  • 销毁
    int pthread_cond_destroy(pthread_cond_t *cond);
    
  • 等待
    int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
    
  • 唤醒
    int pthread_cond_signal(pthread_cond_t *cond); // 唤醒首个
    int pthread_cond_broadcast(pthread_cond_t *cond); // 唤醒全部
    

示例:主线程控制子线程活动

#include <iostream>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
void* Routine(void* arg) {pthread_detach(pthread_self());std::cout << (char*)arg << " run..." << std::endl;while (true) {pthread_cond_wait(&cond, &mutex);std::cout << (char*)arg << "活动..." << std::endl;}
}
int main() {pthread_mutex_init(&mutex, nullptr);pthread_cond_init(&cond, nullptr);pthread_t t1, t2, t3;pthread_create(&t1, nullptr, Routine, (void*)"thread 1");pthread_create(&t2, nullptr, Routine, (void*)"thread 2");pthread_create(&t3, nullptr, Routine, (void*)"thread 3");while (true) {getchar();pthread_cond_signal(&cond); // 逐个唤醒// pthread_cond_broadcast(&cond); // 全部唤醒}pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

为什么pthread_cond_wait需要互斥量

  • 同步需求:条件需由另一线程改变共享数据触发。
  • 死锁问题:若不释放锁,等待时持有锁导致死锁。
  • 功能
    • 等待时释放锁。
    • 被唤醒时自动加锁。
  • 错误设计
    pthread_mutex_lock(&mutex);
    while (condition_is_false) {pthread_mutex_unlock(&mutex); // 非原子pthread_cond_wait(&cond); // 可能错过信号pthread_mutex_lock(&mutex);
    }
    

条件变量使用规范

  • 等待
    pthread_mutex_lock(&mutex);
    while (condition_is_false)pthread_cond_wait(&cond, &mutex);
    // 修改条件
    pthread_mutex_unlock(&mutex);
    
  • 唤醒
    pthread_mutex_lock(&mutex);
    // 设置条件为真
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    

总结

  • 互斥:通过互斥量保护临界资源,确保数据一致性。
  • 同步:条件变量配合锁实现有序访问,避免竞态和饥饿。
  • 安全:理解可重入与线程安全,防范死锁。
http://www.dtcms.com/wzjs/24855.html

相关文章:

  • 网站建设软著杭州网站外包
  • 本地生活网站建设培训机构需要哪些证件
  • 第三方做的网站不给源代码青岛做网站推广公司
  • 网站开发逻辑站长工具seo综合查询官网
  • 网站 做实名认证流感用什么药最好
  • 深圳网站建设-中国互联专门开发小程序的公司
  • 安徽建设厅考勤网站win7优化大师好不好
  • 鲜花培训网站建设sem优化师
  • 网站开发的需要的技术人员企业产品网络推广
  • 网站制作小图标seo发帖网站
  • 专题网站建设策划书无锡网站建设方案优化
  • 企业网站建设的误区主要有seo服务外包客服
  • 泰安专业网站建设discuz论坛seo设置
  • 大型网站开发 赚钱seo如何优化网站
  • 赌博游戏网站建设站长之家域名信息查询
  • 怎么让百度搜出自己windows优化大师电脑版
  • 做网站有什么优势免费制作小程序平台
  • 购物网站css模板网站推广的营销策划方案
  • 网站开发与应用论文百度文库新手学seo
  • 武汉 网站 合作百度关键字优化价格
  • 网站建设门户烟台百度推广公司
  • 上海十大广告公司排名优化服务公司
  • 网站建设 网站杭州seo关键字优化
  • 网站描述设置天津做网站的
  • 学校网站建设的目的网盘搜索引擎入口
  • 武汉 网站建设推广引流最快的方法
  • 惠州定制网站制作推荐百度公司排名
  • 怎么样做企业网站站长之家排名查询
  • 建设银行亚洲网站网推怎么做最有效
  • 响应式网站能用dw做吗就业seo好还是sem