当前位置: 首页> 文旅> 酒店 > 物流公司简介模板_出口跨境电子商务_关键词排名批量查询_做网销的一天都在干嘛

物流公司简介模板_出口跨境电子商务_关键词排名批量查询_做网销的一天都在干嘛

时间:2025/7/13 2:47:03来源:https://blog.csdn.net/weixin_53042232/article/details/142437705 浏览次数:0次
物流公司简介模板_出口跨境电子商务_关键词排名批量查询_做网销的一天都在干嘛

1、阻塞与非阻塞I/O

         阻塞和非阻塞I/O是访问设备的两种不同模式,驱动程序可以灵活地支持用户空间对设备的这两种访问方式。阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。而非阻塞操作的进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直至可以进行操作为止

2、阻塞I/O的实现方式

        等待队列。在Linux驱动程序中,可以使用等待队列(wait queue)来实现阻塞进程的唤醒。wait queue很早就作为一个基本的功能单位出现在Linux内核里了,它以队列为基础数据结构,与进程调度机制紧密结合,能够用于实现内核中的异步事件通知机制。等待队列可以用来同步对系统资源的访问,信号量机制在内核中

也依赖于等待队列实现。

1、定义等待队列头

wait_queue_head_t my_queue;

2、初始化等待队列头

init_waitqueue_head(&my_queue);

3、定义等待队列

DECLARE_WAITQUEUE(name,tsk);

4、添加/移除等待队列

void add_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);
void remove_wait_queue(wait_queue_head_t *q,wait_queue_t *wait);

        add_wait_queue()用于将等待队列wait添加到等待队列头q指向的等待队列链表中,而remove_wait_queue()用于将等待队列wait从附属的等待队列头q指向的等待队列链表中移除。

5、等待事件

wait_event(queue,conditon);
wait_event_interruptible(queue,condition);
wait_event_timeout(queue,condition,timeout);
wait_event_interruptible_timeout(queue,condition,timeout);

        等待第一个参数queue作为等待队列头的等待队列被唤醒,而且第二个参数condition必须满足,否则阻塞。wait_event()和wait_event_interruptible()的区别在于后者可以被信号打断,而前者不能。加上timeout后的宏意味着阻塞等待的超时时间,在第三个参数timeout到达时,不论condition是否满足,均返回。

6、唤醒队列

void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);

       

7、在等待队列上睡眠

sleep_on(wait_queue_head_t *q);
interruptible_sleep_on(wait_queue_head_t *q);

globalfifo的实现。globalfifo根据结构体globalfifo_dev中的信号量,互斥进行读写操作。要注意信号量初始化需赋值为1。因为down操作获取信号量时根据信号量值是否大于0来判断信号量是否可以获取。在读进程中,如果fifo缓冲区为空,就会挂起,等待写进程唤醒。同理,在写进程中,如果fifo缓冲区满,就会挂起,等待读进程唤醒。

#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/bits.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/pmbus.h>
#include <linux/util_macros.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/platform_device.h>
#define GLOBALFIFO_SIZE 20
int globalfifo_major=0;
struct class *globalfifo_class;
struct globalfifo_dev{//struct cdev cdev;//cdev结构体unsigned int current_len;//fifo有效数据长度unsigned char mem[GLOBALFIFO_SIZE];//全局内存123struct semaphore sem;//并发控制用的信号量wait_queue_head_t r_wait;//阻塞读用的等待队列头wait_queue_head_t w_wait;//阻塞写用的等待队列头
};
struct globalfifo_dev *globalfifo_devp;int globalfifo_open(struct inode *node, struct file *filp)
{printk(KERN_INFO"globalfifo_open\n");filp->private_data = globalfifo_devp;printk(KERN_INFO"private_data\n");return 0;
}
int globalfifo_release(struct inode *node, struct file *filp)
{printk(KERN_INFO"globalfifo_release\n");return 0;
}
ssize_t globalfifo_read(struct file *filp, char *buf, size_t size, loff_t *offset)
{printk(KERN_INFO"globalfifo_read\n");int ret;struct globalfifo_dev *dev = filp->private_data;printk(KERN_INFO"read try to declare queue\n");DECLARE_WAITQUEUE(wait,current);printk(KERN_INFO"read try to get sem\n");down(&dev->sem);printk(KERN_INFO"read have got sem\n");add_wait_queue(&dev->r_wait,&wait);if(dev->current_len==0){if(filp->f_flags & O_NONBLOCK){ret = -EAGAIN;goto out;}__set_current_state(TASK_INTERRUPTIBLE);up(&dev->sem);printk(KERN_INFO"read release sem,begin shcedule\n");schedule();if(signal_pending(current)){ret = -ERESTARTSYS;goto out2;}down(&dev->sem);}if(size > dev->current_len)size = dev->current_len;if(copy_to_user(buf,dev->mem,size)){ret = -EFAULT;goto out;}else{//printk("%s",kern_buf);memcpy(dev->mem,dev->mem+size,dev->current_len-size);dev->current_len-=size;printk(KERN_INFO"read %d bytes(s),current_len:%d\n",size,dev->current_len);wake_up_interruptible(&dev->w_wait);ret = size;}out:up(&dev->sem);out2:remove_wait_queue(&dev->r_wait,&wait);set_current_state(TASK_RUNNING);return size;
}
ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{printk("global_fifo write");struct globalfifo_dev *dev = filp->private_data;int ret,i=0,j;DECLARE_WAITQUEUE(wait,current);down(&dev->sem);add_wait_queue(&dev->w_wait,&wait);if(dev->current_len == GLOBALFIFO_SIZE){if(filp->f_flags & O_NONBLOCK){ret = -EAGAIN;goto out;}__set_current_state(TASK_INTERRUPTIBLE);up(&dev->sem);schedule();if(signal_pending(current)){ret = -ERESTARTSYS;goto out2;}down(&dev->sem);}if(size>GLOBALFIFO_SIZE-dev->current_len){size = GLOBALFIFO_SIZE-dev->current_len;}//for(i=dev->current_len,j=0;i<dev->current_len+size;i++,j++)dev->mem[i]=buf[j];if(copy_from_user(dev->mem + dev->current_len,buf,size)){ret = -EFAULT;goto out;}else{dev->current_len+=size;printk(KERN_INFO"written %d bytes(s),current_len:%d\n",size,dev->current_len);wake_up_interruptible(&dev->r_wait);ret = size;}out:up(&dev->sem);out2:remove_wait_queue(&dev->w_wait,&wait);set_current_state(TASK_RUNNING);return ret;}struct file_operations globalfifo_drv={.owner   = THIS_MODULE,.open    = globalfifo_open,.release = globalfifo_release,.read    = globalfifo_read,.write   = globalfifo_write,
};
int globalfifo_init(void)
{int ret;//申请设备号globalfifo_major = register_chrdev(0,"globalfifo",&globalfifo_drv);globalfifo_class = class_create("globalfifo_class");if (IS_ERR(globalfifo_class)) {printk(KERN_ERR "globalfifo_class: failed to allocate class\n");return PTR_ERR(globalfifo_class);}device_create(globalfifo_class,NULL,MKDEV(globalfifo_major,0),NULL,"globalfifo_device");globalfifo_devp = kmalloc(sizeof(struct globalfifo_dev),GFP_KERNEL);if(!globalfifo_devp){ret = -ENOMEM;goto fail_malloc;}memset(globalfifo_devp,0,sizeof(struct globalfifo_dev));//globalfifo_setup_cdev(globalfifo_devp,0);sema_init(&globalfifo_devp->sem,1);init_waitqueue_head(&globalfifo_devp->r_wait);init_waitqueue_head(&globalfifo_devp->w_wait);return 0;fail_malloc:device_destroy(globalfifo_class,MKDEV(globalfifo_major,0));class_destroy(globalfifo_class);unregister_chrdev(globalfifo_major,"globalfifo_chrdev");return ret;
}
void globalfifo_exit(void)
{device_destroy(globalfifo_class,MKDEV(globalfifo_major,0));class_destroy(globalfifo_class);unregister_chrdev(globalfifo_major,"globalfifo_chrdev");return;
}
module_init(globalfifo_init);
module_exit(globalfifo_exit);
MODULE_LICENSE("GPL"); 

3、非阻塞I/O的实现方式

        轮询操作。使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问。


        应用程序中的轮询编程:其中select()系统调用的原型如下,其中readfds、writefds、exceptfds分别是被select()监视的读、写和异常处理的文件描述符集合,numfds的值是需要检查的号码最高的文件描述符加1。timeout参数是一个指向struct timeval类型的指针,可以使select()在等待timeout时间后若没有文件描述符准备好则返回。

int select(int numfds,fd_set *readfds,fd_set *writefds,fd_set *expectfds,struct timeval *timeout);

清除一个文件描述符集::

FD_ZERO(fd_set *set)

将一个文件描述符加入文件描述符集中:
 

FD_SET(int fd,fd_set *set)

将一个文件描述符从文件描述符集中清除:

FD_ISSET(int fd,fd_set *set)

判断文件描述符是否被置位:

FD_ISSET(int fd,fd_set *set)

        设备驱动中的轮询编程:设备驱动中poll()函数的原型如下,第一个参数为file结构体指针,第二个参数为轮询表指针。这个函数应该进行以下两项工作:1、对可能引起设备文件状态变化的等待队列调用poll_wait()函数,将对应的等待队列头添加到poll_table。2、返回表示是否能对设备进行无阻塞读、写访问的掩码。

unsigned int (*poll) (struct file *filp,struct poll_table *wait);

         关键的用于向poll_table注册等待队列的poll_wait()函数原型如下,poll_wait()函数所做的工作是把当前进程添加到wait参数指定的等待列表(poll_table)中,并不会引起阻塞。

void poll_wait(struct file *filp,wait_queue_head_t *queue,poll_table *wait);

        驱动程序poll()函数应该返回设备资源的可获取状态,即POLLIN、POLLOUT、POLLPRI、POLLERR、POLLNVAL等宏的位”或“结果。每个宏的含义都表明设备的一种状态,如POLLIN表可无阻塞读,POLLOUT表可无阻塞写。 poll()函数典型模板如下:

static unsigned int xxx_poll(struct file *filp,poll_table *wait)
{unsigned int mask=0;struct xxx_dev *dev = filp->private_data;poll_wait(filp,&dev->r_wait,wait);poll_wait(filp,&dev->w_wait,wait);if(...)//可读{mask |=  POLLIN | POLLRDNORM;}if(...)//可写{mask |= POLLIN | POLLWRNORM;}return mask;
}

        增加了轮询操作的globalfifo驱动。在驱动中利用poll机制,在应用程序想要读写文件的时候,通过poll函数率先判断读、写资源是否可用,如果不可用则返回资源不可用的信号。如果资源可用则返回可读、写信号。

#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/bits.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/pmbus.h>
#include <linux/util_macros.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/platform_device.h>
#define GLOBALFIFO_SIZE 20
int globalfifo_major=0;
struct class *globalfifo_class;
struct globalfifo_dev{//struct cdev cdev;//cdev结构体unsigned int current_len;//fifo有效数据长度unsigned char mem[GLOBALFIFO_SIZE];//全局内存123struct semaphore sem;//并发控制用的信号量wait_queue_head_t r_wait;//阻塞读用的等待队列头wait_queue_head_t w_wait;//阻塞写用的等待队列头
};
struct globalfifo_dev *globalfifo_devp;int globalfifo_open(struct inode *node, struct file *filp)
{printk(KERN_INFO"globalfifo_open\n");filp->private_data = globalfifo_devp;printk(KERN_INFO"private_data\n");return 0;
}
int globalfifo_release(struct inode *node, struct file *filp)
{printk(KERN_INFO"globalfifo_release\n");return 0;
}
ssize_t globalfifo_read(struct file *filp, char *buf, size_t size, loff_t *offset)
{printk(KERN_INFO"globalfifo_read\n");int ret;struct globalfifo_dev *dev = filp->private_data;printk(KERN_INFO"read try to declare queue\n");DECLARE_WAITQUEUE(wait,current);printk(KERN_INFO"read try to get sem\n");down(&dev->sem);printk(KERN_INFO"read have got sem\n");add_wait_queue(&dev->r_wait,&wait);if(dev->current_len==0){if(filp->f_flags & O_NONBLOCK){ret = -EAGAIN;goto out;}__set_current_state(TASK_INTERRUPTIBLE);up(&dev->sem);printk(KERN_INFO"read release sem,begin shcedule\n");schedule();if(signal_pending(current)){ret = -ERESTARTSYS;goto out2;}down(&dev->sem);}if(size > dev->current_len)size = dev->current_len;if(copy_to_user(buf,dev->mem,size)){ret = -EFAULT;goto out;}else{//printk("%s",kern_buf);memcpy(dev->mem,dev->mem+size,dev->current_len-size);dev->current_len-=size;printk(KERN_INFO"read %d bytes(s),current_len:%d\n",size,dev->current_len);wake_up_interruptible(&dev->w_wait);ret = size;}out:up(&dev->sem);out2:remove_wait_queue(&dev->r_wait,&wait);set_current_state(TASK_RUNNING);return size;
}
ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{printk("global_fifo write");struct globalfifo_dev *dev = filp->private_data;int ret,i=0,j;DECLARE_WAITQUEUE(wait,current);down(&dev->sem);add_wait_queue(&dev->w_wait,&wait);if(dev->current_len == GLOBALFIFO_SIZE){if(filp->f_flags & O_NONBLOCK){ret = -EAGAIN;goto out;}__set_current_state(TASK_INTERRUPTIBLE);up(&dev->sem);schedule();if(signal_pending(current)){ret = -ERESTARTSYS;goto out2;}down(&dev->sem);}if(size>GLOBALFIFO_SIZE-dev->current_len){size = GLOBALFIFO_SIZE-dev->current_len;}//for(i=dev->current_len,j=0;i<dev->current_len+size;i++,j++)dev->mem[i]=buf[j];if(copy_from_user(dev->mem + dev->current_len,buf,size)){ret = -EFAULT;goto out;}else{dev->current_len+=size;printk(KERN_INFO"written %d bytes(s),current_len:%d\n",size,dev->current_len);wake_up_interruptible(&dev->r_wait);ret = size;}out:up(&dev->sem);out2:remove_wait_queue(&dev->w_wait,&wait);set_current_state(TASK_RUNNING);return ret;}
unsigned int globalfifo_poll(struct file *filp, struct poll_table_struct *wait)
{unsigned int mask = 0;struct globalfifo_dev *dev = filp->private_data;down(&dev->sem);poll_wait(filp,&dev->r_wait,wait);poll_wait(filp,&dev->w_wait,wait);if(dev->current_len != 0){mask |= POLLIN | POLLRDNORM;}if(dev->current_len != GLOBALFIFO_SIZE){mask |= POLLOUT | POLLWRNORM;}up(&dev->sem);return mask;
}struct file_operations globalfifo_drv={.owner   = THIS_MODULE,.open    = globalfifo_open,.release = globalfifo_release,.read    = globalfifo_read,.write   = globalfifo_write,.poll    = globalfifo_poll,
};
int globalfifo_init(void)
{int ret;//申请设备号globalfifo_major = register_chrdev(0,"globalfifo",&globalfifo_drv);globalfifo_class = class_create("globalfifo_class");if (IS_ERR(globalfifo_class)) {printk(KERN_ERR "globalfifo_class: failed to allocate class\n");return PTR_ERR(globalfifo_class);}device_create(globalfifo_class,NULL,MKDEV(globalfifo_major,0),NULL,"globalfifo_device");globalfifo_devp = kmalloc(sizeof(struct globalfifo_dev),GFP_KERNEL);if(!globalfifo_devp){ret = -ENOMEM;goto fail_malloc;}memset(globalfifo_devp,0,sizeof(struct globalfifo_dev));//globalfifo_setup_cdev(globalfifo_devp,0);sema_init(&globalfifo_devp->sem,1);init_waitqueue_head(&globalfifo_devp->r_wait);init_waitqueue_head(&globalfifo_devp->w_wait);return 0;fail_malloc:device_destroy(globalfifo_class,MKDEV(globalfifo_major,0));class_destroy(globalfifo_class);unregister_chrdev(globalfifo_major,"globalfifo_chrdev");return ret;
}
void globalfifo_exit(void)
{device_destroy(globalfifo_class,MKDEV(globalfifo_major,0));class_destroy(globalfifo_class);unregister_chrdev(globalfifo_major,"globalfifo_chrdev");return;
}
module_init(globalfifo_init);
module_exit(globalfifo_exit);
MODULE_LICENSE("GPL"); 

关键字:物流公司简介模板_出口跨境电子商务_关键词排名批量查询_做网销的一天都在干嘛

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: