随笔-15  评论-10  文章-1  trackbacks-0
设计模式并非是高级语言才特有的,目前软件开发过程中,有许多代码是可以借鉴的,可以把这些代码
分离出基本的骨架,然后形成模板,用于去集成更加复杂的软件

posted on 2007-09-29 17:24 hzb 阅读(546) 评论(2)  编辑 收藏 引用

评论:
# linux下用户态跟内核态交互的一个模式 2007-09-29 17:30 | go-benny
情景:用户态下的cli程序,需要跟内核态下的软件模块交互
方案:编写一个字符设备作为控制设备,实现cli个内核模块的交互

代码:

1、控制设备驱动

/---------------------------Makefile-------------------------------/
EXTRA_CFLAGS := -I.
obj-m := chrdev.o

all:
make -C /lib/modules/`uname -r`/build M=`pwd`


/---------------------------chrdev.h-------------------------------/
#ifndef __CHRDEV_H__
#define __CHRDEV_H__
#define MAX_DESC_LEN 64
struct chrdev_ioctl {
uint32_t cmd;
char desc[MAX_DESC_LEN];
};
#endif


/---------------------------chrdev.c-------------------------------/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "chrdev.h"


static int my_chrdev_ioctl(struct inode *inode, struct file *file,
unsigned int command, unsigned long u)
{
int r = 0;
unsigned int cmd;
struct chrdev_ioctl param;
struct chrdev_ioctl __user *user = (struct chrdev_ioctl __user *) u;
r = copy_from_user(&param, user, sizeof(param));
if (!r)
return -EFAULT;
cmd = param.cmd;
printk("cmd=%d\n", cmd);
r = copy_to_user(user, &param, sizeof(param));
if (!r)
r = -EFAULT;

return r;
}

static const struct file_operations _ctl_fops= {
.ioctl = my_chrdev_ioctl,
.owner = THIS_MODULE,
};


static struct miscdevice _my_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mychrdev",
.fops = &_ctl_fops
};


int __init chrdev_init(void)
{
int r;
r = misc_register(&_my_misc);
if (r) {
printk("Failed to register a my chrdev.\n");
}
return 0;
}

void __exit chrdev_exit(void)
{
misc_deregister(&_my_misc);
}

module_init(chrdev_init);
module_exit(chrdev_exit);

2、用户态程序

/----------------------------main.c-----------------------------------/

#include <stdio.h>
#include <fcntl.h>

const char *ctl_dev = "/dev/mychrdev";

struct chrdev_ioctl {
unsigned int cmd;
char desc[64];
};

int main()
{
int fd = -1;
int cmd = 999;
struct chrdev_ioctl param;
param.cmd = cmd;

if ((fd = open(ctl_dev, O_RDWR)) < 0) {
return -1;
}
ioctl(fd, cmd, &param);
close(fd);
return 0;
}

[编辑]

  回复  更多评论
  
# re: 模式编程见解 2007-09-29 17:37 | go-benny
情景:网络编程时处理一对多的情况

方案:采用epoll模式实现。开源项目IET(iscsi enterprise target)采用了poll的模型,
据说epoll比poll更好,由于没有需求,所以我不深入研究。

以下是网上拷的代码片段

/*-------------------------------------------------------------------------------------------------
gcc -o httpd httpd.c -lpthread
author: wyezl
2006.4.28
---------------------------------------------------------------------------------------------------*/

#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>

#define PORT 8888
#define MAXFDS 5000
#define EVENTSIZE 100

#define BUFFER "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nConnection: close\r\nContent-Type: text/html\r\n\r\nHello"

int epfd;
void *serv_epoll(void *p);
void setnonblocking(int fd)
{
int opts;
opts=fcntl(fd, F_GETFL);
if (opts < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
opts = opts | O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts) < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
return;
}

int main(int argc, char *argv[])
{
int fd, cfd,opt=1;
struct epoll_event ev;
struct sockaddr_in sin, cin;
socklen_t sin_len = sizeof(struct sockaddr_in);
pthread_t tid;
pthread_attr_t attr;

epfd = epoll_create(MAXFDS);
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
{
fprintf(stderr, "socket failed\n");
return -1;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));

memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons((short)(PORT));
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0)
{
fprintf(stderr, "bind failed\n");
return -1;
}
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if (pthread_create(&tid, &attr, serv_epoll, NULL) != 0)
{
fprintf(stderr, "pthread_create failed\n");
return -1;
}

while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
{
setnonblocking(cfd);
ev.data.fd = cfd;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
//printf("connect from %s\n",inet_ntoa(cin.sin_addr));

//printf("cfd=%d\n",cfd);

}

if (fd > 0)
close(fd);
return 0;
}

void *serv_epoll(void *p)
{
int i, ret, cfd, nfds;;
struct epoll_event ev,events[EVENTSIZE];
char buffer[512];

while (1)
{
nfds = epoll_wait(epfd, events, EVENTSIZE , -1);
//printf("nfds ........... %d\n",nfds);

for (i=0; i<nfds; i++)
{
if(events[i].events & EPOLLIN)
{
cfd = events[i].data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);


ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
else if(events[i].events & EPOLLOUT)
{
cfd = events[i].data.fd;
ret = send(cfd, BUFFER, strlen(BUFFER), 0);
//printf("send ret...........= %d\n", ret);


ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
//shutdown(cfd, 1);

close(cfd);

}
}
}
return NULL;
}
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理