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

网站不备案可以做百度推广吗bt种子磁力搜索引擎

网站不备案可以做百度推广吗,bt种子磁力搜索引擎,wordpress 前台标签,快速做网站公司报价前面内容对自旋锁和自旋锁死锁进行了了解, 自旋锁会让请求的任务原地“自旋” ,在等待的过程中会循环检测自旋锁的状态, 进而占用系统资源, 而本章节要讲解的信号量也是解决竞争的一种常用方法, 与自旋锁不同的是&…

前面内容对自旋锁和自旋锁死锁进行了了解, 自旋锁会让请求的任务原地“自旋” ,在等待的过程中会循环检测自旋锁的状态, 进而占用系统资源, 而本章节要讲解的信号量也是解决竞争的一种常用方法, 与自旋锁不同的是, 信号量会使等待的线程进入休眠状态, 适用于那些占用资源比较久的场合

文章目录

  • 参考资料
  • 信号量介绍
  • 信号量结构体 - semaphore
  • 信号量API
  • 信号量实验
    • 源码程序-semaphore.c
      • 部分源码解读
    • 编译脚本 Makefile
    • 测试程序 app.c
    • 准备测试命令和测试脚本-app.sh
      • 测试命令
      • 测试脚本
    • 加载驱动 insmod
      • 查看 dev 下生成的字符设备
    • 测试验证信号量程序
      • 直接命令后台验证
      • 脚本批量执行后台任务 测试验证
  • 总结


参考资料

前面了解了原子操作和自旋锁,当然还有之前的字符设备相关操作,前面基础知识还是需要重点掌握的,才能将知识点串联起来:

接下来还是以前面字符设备 动态参数传递实验为基础,打开访问字符设备实验。 所以以前知识点 建议了解
在字符设备这块内容,所有知识点都是串联起来的,需要整体来理解,缺一不可,建议多了解一下基础知识
驱动-申请字符设备号
驱动-注册字符设备
驱动-创建设备节点
驱动-字符设备驱动框架
驱动-杂项设备
驱动-内核空间和用户空间数据交换
驱动-文件私有数据
Linux驱动之 原子操作
Linux驱动—原子操作
驱动-自旋锁
驱动-自旋锁死锁

信号量介绍

  • 信号量是操作系统中最典型的用于同步和互斥的手段, 本质上是一个全局变量, 信号量的值表示控制访问资源的线程数,可以根据实际情况来自行设置, 如果在初始化的时候将信号量量值设置为大于 1, 那么这个信号量就是计数型信号量,允许多个线程同时访问共享资源。 如果将信号量量值设置为 1, 那么这个信号量就是二值信号量, 同一时间内只允许一个线程访问共享资源,注意! 信号量的值不能小于 0。 当信号量的值为 0 时, 想访问共享资源的线程必须等待, 直到信号量大于 0 时,等待的线程才可以访问。 当访问共享资源时, 信号量执行“减一”操作, 访问完成后再执行“加一” 操作。

  • 相比于自旋锁, 信号量具有休眠特性, 因此适用长时间占用资源的场合, 但由于信号量会引起休眠, 所以不能用在中断函数中,最后如果共享资源的持有时间比较短, 使用信号量的话会造成频繁的休眠, 反而带来更多资源的消耗, 使用自旋锁反而效果更好。 再同时使用信号量和自旋锁的时候, 要先获取信号量, 再使用自旋锁, 因为信号量会导致睡眠

  • 以现实生活中的银行办理业务为例, 银行的业务办理窗口就是共享资源, 业务办理窗口的数量就是信号量量值, 进入银行之后, 客户需要领取相应的排序码, 然后在休息区进行等待,可以看作线程的睡眠阶段, 当前面的客户办理完业务之后, 相应的窗口会空闲出来, 可以看作信号量的释放, 之后银行会通过广播, 提醒下一位客户到指定的窗口进行业务的办理, 可以看作线程的唤醒并获取到信号量, 访问共享资源的过程。

信号量结构体 - semaphore

Linux 内核使用 semaphore 结构体来表示信号量,如下:

struct semaphore {
raw_spinlock_t lock;
unsigned int count;
struct list_head wait_list;
};

信号量API

在这里插入图片描述

信号量实验

源码程序-semaphore.c

这个源码程序,用到的还是访问字符设备的最基本内容来讲解,另外添加了 信号量api 来规避并发和竞争

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/errno.h>
#include <linux/semaphore.h>struct semaphore semaphore_test;//定义一个semaphore类型的结构体变量semaphore_teststatic int open_test(struct  inode  *inode,struct file *file){printk("\n this is open_test \n");down(&semaphore_test);//信号量数量减1return 0;};static ssize_t read_test(struct file *file,char __user *ubuf,size_t len,loff_t *off)
{int ret;char kbuf[10] = "topeet";//定义char类型字符串变量kbufprintk("\nthis is read_test \n");ret = copy_to_user(ubuf,kbuf,strlen(kbuf));//使用copy_to_user接收用户空间传递的数据if (ret != 0){printk("copy_to_user is error \n");}printk("copy_to_user is ok \n");return 0;
}
static char kbuf[10] = {0};//定义char类型字符串全局变量kbuf
static ssize_t write_test(struct file *file,const char __user *ubuf,size_t len,loff_t *off)
{int ret;ret = copy_from_user(kbuf,ubuf,len);//使用copy_from_user接收用户空间传递的数据if (ret != 0){printk("copy_from_user is error\n");}if(strcmp(kbuf,"topeet") == 0 ){//如果传递的kbuf是topeet就睡眠四秒钟ssleep(4);}else if(strcmp(kbuf,"itop") == 0){//如果传递的kbuf是itop就睡眠两秒钟ssleep(2);}printk("copy_from_user buf is %s \n",kbuf);return 0;
}
static int release_test(struct inode *inode,struct file *file)
{printk("\nthis is release_test \n");up(&semaphore_test);//信号量数量加1return 0;
}struct chrdev_test
{dev_t  dev_num;  //定义dev_t类型变量来表示设备号int major,minor; //定义int 类型的主设备号和次设备号struct cdev cdev_test;   //定义字符设备struct class *class_test;   //定义结构体变量class 类
};struct chrdev_test dev1; //创建chardev_test类型结构体变量static struct file_operations fops_test = {.owner=THIS_MODULE,//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块.open = open_test,//将open字段指向chrdev_open(...)函数.read = read_test,//将open字段指向chrdev_read(...)函数.write = write_test,//将open字段指向chrdev_write(...)函数.release = release_test,//将open字段指向chrdev_release(...)函数
};//定义file_operations结构体类型的变量cdev_test_opsstatic int __init chrdev_fops_init(void)//驱动入口函数
{sema_init(&semaphore_test,1);//初始化信号量结构体semaphore_test,并设置信号量的数量为1if(alloc_chrdev_region(&dev1.dev_num,0,1,"chrdev_name") < 0){printk("alloc_chrdev_region is error\n");}   printk("alloc_chrdev_region is ok\n");dev1.major=MAJOR(dev1.dev_num);//通过MAJOR()函数进行主设备号获取dev1.minor=MINOR(dev1.dev_num);//通过MINOR()函数进行次设备号获取printk("major is %d\n",dev1.major);printk("minor is %d\n",dev1.minor);使用cdev_init()函数初始化cdev_test结构体,并链接到cdev_test_ops结构体cdev_init(&dev1.cdev_test,&fops_test);dev1.cdev_test.owner = THIS_MODULE;//将owner字段指向本模块,可以避免在模块的操作正在被使用时卸载该模块 cdev_add(&dev1.cdev_test,dev1.dev_num,1);printk("cdev_add is ok\n");dev1.class_test  = class_create(THIS_MODULE,"class_test");//使用class_create进行类的创建,类名称为class_testdevice_create(dev1.class_test,NULL,dev1.dev_num,NULL,"device_test");//使用device_create进行设备的创建,设备名称为device_testreturn 0;
}
static void __exit chrdev_fops_exit(void)//驱动出口函数
{cdev_del(&dev1.cdev_test);//使用cdev_del()函数进行字符设备的删除unregister_chrdev_region(dev1.dev_num,1);//释放字符驱动设备号 device_destroy(dev1.class_test,dev1.dev_num);//删除创建的设备class_destroy(dev1.class_test);//删除创建的类printk("module exit \n");}
module_init(chrdev_fops_init);//注册入口函数
module_exit(chrdev_fops_exit);//注册出口函数
MODULE_LICENSE("GPL v2");//同意GPL开源协议
MODULE_AUTHOR("wang fang chen "); //作者信息

部分源码解读

字符设备操作这里不再赘述,重点看看信号量怎么用的。
在之前学习过原子操作设置标志位, 在同一时间内只允许一个任务对共享资源进行访问的方式所不
同, 这里将采用信号量的方式避免竞争的产生。 本实验设置的信号量量值为 1, 所以需要在
open()函数中加入信号量获取函数, 在 release()函数中加入信号量释放函数即可。同时要记得初始化哦。

  • 定义结构体 - semaphore
struct semaphore semaphore_test;//定义一个semaphore类型的结构体变量semaphore_test
  • 驱动入口函数 init 中初始化 信号量结构体,设置值 - sema_init
static int __init chrdev_fops_init(void)//驱动入口函数
{sema_init(&semaphore_test,1);//初始化信号量结构体semaphore_test,并设置信号量的数量为1
...
}
  • 在open 中消费信号量 - down
static int open_test(struct  inode  *inode,struct file *file){printk("\n this is open_test \n");down(&semaphore_test);//信号量数量减1return 0;};
  • 程序释放资源时候,恢复信号量- up
static int release_test(struct inode *inode,struct file *file)
{printk("\nthis is release_test \n");up(&semaphore_test);//信号量数量加1return 0;
}

编译脚本 Makefile

#!/bin/bash
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
obj-m += semaphore.o
KDIR :=/home/wfc123/Linux/rk356x_linux/kernel
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

测试程序 app.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{int fd;                           // 定义int类型的文件描述符char str1[10] = {0};              // 定义读取缓冲区str1fd = open(argv[1], O_RDWR, 0666); // 调用open函数,打开输入的第一个参数文件,权限为可读可写// fd=open("/dev/device_test",O_RDWR,0666);//调用open函数,打开输入的第一个参数文件,权限为可读可写if (fd < 0){printf("open is error\n");return -1;}printf("open is ok\n");if (strcmp(argv[2], "topeet") == 0){write(fd, "topeet", sizeof(str1));}else if (strcmp(argv[2], "itop") == 0){write(fd, "itop", sizeof(str1));}close(fd); // 调用close函数,对取消文件描述符到文件的映射return 0;
}

编译 测试程序 app

aarch64-linux-gnu-gcc -o app app.c -static

准备测试命令和测试脚本-app.sh

测试命令

同时后台执行两个命令

./app /dev/device_test topeet &
./app /dev/device_test itop

测试脚本

这里准备签名驱动自选死锁的脚本,方便看看信号量的作用和效果。 app.sh

[root@topeet:/mnt/sdcard]# cat app.sh#!/bin/bash
taskset -c 0 ./app /dev/device_test topeet &
taskset -c 1 ./app /dev/device_test topeet &
taskset -c 2 ./app /dev/device_test topeet &
taskset -c 3 ./app /dev/device_test topeet &
taskset -c 0 ./app /dev/device_test topeet &
taskset -c 1 ./app /dev/device_test topeet &
taskset -c 2 ./app /dev/device_test topeet &
taskset -c 3 ./app /dev/device_test topeet &

加载驱动 insmod

加载驱动后,看一下字符相关操作是否有相关打印,从结果上看打印OK,逻辑正常在走。
在这里插入图片描述

查看 dev 下生成的字符设备

字符设备都已经生成了,说明测试程序没有问题的。
在这里插入图片描述

测试验证信号量程序

直接命令后台验证

./app /dev/device_test topeet &
./app /dev/device_test itop

看实验结果如下:文件操作是一个等着一个执行的呢
在这里插入图片描述

脚本批量执行后台任务 测试验证

实际结果是,打印一个接着一个打印,会按照程序里面的逻辑 等待几秒,执行完后才会执行下一个任务命令。 而且最重要的是 这里用的是自旋锁死锁的 脚本来验证,在信号量这里不会死机。 这样更方便理解信号量的原理了。
在这里插入图片描述

总结

  • 信号量也是解决并发、竞争问题的一种方案
  • 浅显的看:信号量原理就是一个全局的变量,类似于原子操作。会让线程、进程去处理其它事情,不用想自旋锁原地等待。大量频繁使用会增加切换资源消耗。
  • 对于耗时任务 是它的一个使用场景
http://www.dtcms.com/wzjs/465814.html

相关文章:

  • 公司网站的推广方案2021年重大新闻事件
  • 做淘宝图的素材搜索网站万网域名注册查询
  • 江苏做网站公司有哪些小程序开发框架
  • 宜昌便宜做网站个人网站如何优化关键词
  • 网站规划小结市场营销手段有哪四种
  • 做网站_接活谷歌网站推广优化
  • 网站被降权恢复福州网站开发公司
  • 武汉鞋业营销型网站建设网站建设需要多少钱?
  • 怀化主要网站最好用的磁力搜索器
  • 服务器 做网站关键词规划师
  • 网站上传程序流程咖啡的营销推广软文
  • 万能建站网站seo关键词选择及优化
  • 视觉传播设计与制作专业google seo 优化教程
  • 深圳建设厅网站北京seoqq群
  • 如何做美食的视频网站优化关键词排名推广
  • 天河区做网站公司设计案例网
  • 网站建设仪器配置表竞价推广是什么工作
  • 跨境浏览网站郑州seo外包收费标准
  • 网站建设内容录入论文快速网站推广公司
  • abduzeedo是什么网站今日百度小说排行榜风云榜
  • 网站的营销方案深圳网络推广培训
  • 日照网站制作公司高端网站设计定制
  • 网站基本建设百度seo点击
  • aspnet网站开发教程沈阳网站关键词优化公司
  • 河南省网站建设关键词歌曲免费听
  • 上海网站seo招聘网络域名
  • 网站编辑器是怎么做的百度统计
  • 我的网站怎么做2023年5月份病毒感染情况
  • 做期货在哪个网站看消息品牌全网推广
  • 国外创意海报设计网站seo快速排名软件平台