ºìÁªLinuxÃÅ»§
Linux°ïÖú

LinuxÉ豸Çý¶¯±à³ÌÖ®×èÈûÓë·Ç×èÈû

·¢²¼Ê±¼ä:2006-10-23 10:03:04À´Ô´:ºìÁª×÷Õß:Informix
¡¡¡¡×èÈû²Ù×÷ÊÇÖ¸£¬ÔÚÖ´ÐÐÉ豸²Ù×÷ʱ£¬Èô²»ÄÜ»ñµÃ×ÊÔ´£¬Ôò½ø³Ì¹ÒÆðÖ±µ½Âú×ã¿É²Ù×÷µÄÌõ¼þÔÙ½øÐвÙ×÷¡£·Ç×èÈû²Ù×÷µÄ½ø³ÌÔÚ²»ÄܽøÐÐÉ豸²Ù×÷ʱ£¬²¢²»¹ÒÆð¡£±»¹ÒÆðµÄ½ø³Ì½øÈësleep״̬£¬±»´Óµ÷¶ÈÆ÷µÄÔËÐжÓÁÐÒÆ×ߣ¬Ö±µ½µÈ´ýµÄÌõ¼þ±»Âú×ã¡£

¡¡¡¡ÔÚLinuxÇý¶¯³ÌÐòÖУ¬ÎÒÃÇ¿ÉÒÔʹÓõȴý¶ÓÁУ¨wait queue£©À´ÊµÏÖ×èÈû²Ù×÷¡£wait queueºÜÔç¾Í×÷Ϊһ¸ö»ù±¾µÄ¹¦Äܵ¥Î»³öÏÖÔÚLinuxÄÚºËÀïÁË£¬ËüÒÔ¶ÓÁÐΪ»ù´¡Êý¾Ý½á¹¹£¬Óë½ø³Ìµ÷¶È»úÖƽôÃܽáºÏ£¬Äܹ»ÓÃÓÚʵÏÖºËÐĵÄÒ첽ʼþ֪ͨ»úÖÆ¡£µÈ´ý¶ÓÁпÉÒÔÓÃÀ´Í¬²½¶Ôϵͳ×ÊÔ´µÄ·ÃÎÊ£¬ÉϽÚÖÐËù½²ÊöLinuxÐźÅÁ¿ÔÚÄÚºËÖÐÒ²ÊÇÓɵȴý¶ÓÁÐÀ´ÊµÏֵġ£

¡¡¡¡ÏÂÃæÎÒÃÇÖØж¨ÒåÉ豸"globalvar"£¬Ëü¿ÉÒÔ±»¶à¸ö½ø³Ì´ò¿ª£¬µ«ÊÇÿ´ÎÖ»Óе±Ò»¸ö½ø³ÌдÈëÁËÒ»¸öÊý¾ÝÖ®ºó±¾½ø³Ì»òÆäËü½ø³Ì²Å¿ÉÒÔ¶ÁÈ¡¸ÃÊý¾Ý£¬·ñÔòÒ»Ö±×èÈû¡£

[code]#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");

#define MAJOR_NUM 254

static ssize_t globalvar_read(struct file *, char *, size_t, loff_t*);
static ssize_t globalvar_write(struct file *, const char *, size_t, loff_t*);

struct file_operations globalvar_fops =
{
¡¡read: globalvar_read, write: globalvar_write,
};

static int global_var = 0;
static struct semaphore sem;
static wait_queue_head_t outq;
static int flag = 0;

static int __init globalvar_init(void)
{
¡¡int ret;
¡¡ret = register_chrdev(MAJOR_NUM, "globalvar", &globalvar_fops);
¡¡if (ret)
¡¡{
¡¡¡¡printk("globalvar register failure");
¡¡}
¡¡else
¡¡{
¡¡¡¡printk("globalvar register success");
¡¡¡¡init_MUTEX(&sem);
¡¡¡¡init_waitqueue_head(&outq);
¡¡}
¡¡return ret;
}

static void __exit globalvar_exit(void)
{
¡¡int ret;
¡¡ret = unregister_chrdev(MAJOR_NUM, "globalvar");
¡¡if (ret)
¡¡{
¡¡¡¡printk("globalvar unregister failure");
¡¡}
¡¡else
¡¡{
¡¡¡¡printk("globalvar unregister success");
¡¡}
}

static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
¡¡//µÈ´ýÊý¾Ý¿É»ñµÃ
¡¡if (wait_event_interruptible(outq, flag != 0))
¡¡{
¡¡¡¡return - ERESTARTSYS;
¡¡}

¡¡if (down_interruptible(&sem))
¡¡{
¡¡¡¡return - ERESTARTSYS;
¡¡}

¡¡flag = 0;
¡¡if (copy_to_user(buf, &global_var, sizeof(int)))
¡¡{
¡¡¡¡up(&sem);
¡¡¡¡return - EFAULT;
¡¡}
¡¡up(&sem);
¡¡return sizeof(int);
}

static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len,loff_t *off)
{
¡¡if (down_interruptible(&sem))
¡¡{
¡¡¡¡return - ERESTARTSYS;
¡¡}
¡¡if (copy_from_user(&global_var, buf, sizeof(int)))
¡¡{
¡¡¡¡up(&sem);
¡¡¡¡return - EFAULT;
¡¡}
¡¡up(&sem);
¡¡flag = 1;
¡¡//֪ͨÊý¾Ý¿É»ñµÃ
¡¡wake_up_interruptible(&outq);
¡¡return sizeof(int);
}

module_init(globalvar_init);
module_exit(globalvar_exit);[/code]

¡¡¡¡±àдÁ½¸öÓû§Ì¬µÄ³ÌÐòÀ´²âÊÔ£¬µÚÒ»¸öÓÃÓÚ×èÈûµØ¶Á/dev/globalvar£¬ÁíÒ»¸öÓÃÓÚд/dev/globalvar¡£Ö»Óе±ºóÒ»¸ö¶Ô/dev/globalvar½øÐÐÁËÊäÈëÖ®ºó£¬Ç°ÕßµÄread²ÅÄÜ·µ»Ø¡£

¡¡¡¡¶ÁµÄ³ÌÐòΪ£º

[code]#include
#include
#include
#include
main()
{
¡¡int fd, num;

¡¡fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
¡¡if (fd != - 1)
¡¡{
¡¡¡¡while (1)
¡¡¡¡{
¡¡¡¡¡¡read(fd, &num, sizeof(int)); //³ÌÐò½«×èÈûÔÚ´ËÓï¾ä£¬³ý·ÇÓÐÕë¶ÔglobalvarµÄÊäÈë
¡¡¡¡¡¡printf("The globalvar is %d\n", num);

¡¡¡¡¡¡//Èç¹ûÊäÈëÊÇ0£¬ÔòÍ˳ö
¡¡¡¡¡¡if (num == 0)
¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡close(fd);
¡¡¡¡¡¡¡¡break;
¡¡¡¡¡¡}
¡¡¡¡}
¡¡}
¡¡else
¡¡{
¡¡¡¡printf("device open failure\n");
¡¡}
}[/code]
¡¡¡¡Ð´µÄ³ÌÐòΪ£º

[code]#include
#include
#include
#include
main()
{
¡¡int fd, num;

¡¡fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
¡¡if (fd != - 1)
¡¡{
¡¡¡¡while (1)
¡¡¡¡{
¡¡¡¡¡¡printf("Please input the globalvar:\n");
¡¡¡¡¡¡scanf("%d", &num);
¡¡¡¡¡¡write(fd, &num, sizeof(int));

¡¡¡¡¡¡//Èç¹ûÊäÈë0£¬Í˳ö
¡¡¡¡¡¡if (num == 0)
¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡close(fd);
¡¡¡¡¡¡¡¡break;
¡¡¡¡¡¡}
¡¡¡¡}
¡¡}
¡¡else
¡¡{
¡¡¡¡printf("device open failure\n");
¡¡}
}[/code]
¡¡¡¡´ò¿ªÁ½¸öÖնˣ¬·Ö±ðÔËÐÐÉÏÊöÁ½¸öÓ¦ÓóÌÐò£¬·¢ÏÖµ±ÔÚµÚ¶þ¸öÖÕ¶ËÖÐûÓÐÊäÈëÊý¾Ýʱ£¬µÚÒ»¸öÖÕ¶ËûÓÐÊä³ö£¨×èÈû£©£¬Ã¿µ±ÎÒÃÇÔÚµÚ¶þ¸öÖÕ¶ËÖиøglobalvarÊäÈëÒ»¸öÖµ£¬µÚÒ»¸öÖն˾ͻáÊä³öÕâ¸öÖµ£¬ÈçÏÂͼ£º

[align=center][/align]

¡¡¡¡¹ØÓÚÉÏÊöÀý³Ì£¬ÎÒÃDz¹³ä˵һµã£¬Èç¹û½«Çý¶¯³ÌÐòÖеÄreadº¯Êý¸ÄΪ£º

[code]static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off)
{
¡¡//»ñÈ¡ÐźÅÁ¿£º¿ÉÄÜ×èÈû
¡¡if (down_interruptible(&sem))
¡¡{
¡¡¡¡return - ERESTARTSYS;
¡¡}

¡¡//µÈ´ýÊý¾Ý¿É»ñµÃ£º¿ÉÄÜ×èÈû
¡¡if (wait_event_interruptible(outq, flag != 0))
¡¡{
¡¡¡¡return - ERESTARTSYS;
¡¡}
¡¡flag = 0;

¡¡//ÁÙ½ç×ÊÔ´·ÃÎÊ
¡¡if (copy_to_user(buf, &global_var, sizeof(int)))
¡¡{
¡¡¡¡up(&sem);
¡¡¡¡return - EFAULT;
¡¡}

¡¡//ÊÍ·ÅÐźÅÁ¿
¡¡up(&sem);

¡¡return sizeof(int);
}[/code]
¡¡¡¡¼´½»»»wait_event_interruptible(outq, flag != 0)ºÍdown_interruptible(&sem)µÄ˳Ðò£¬Õâ¸öÇý¶¯³ÌÐò½«±äµÃ²»¿ÉÔËÐС£Êµ¼ÊÉÏ£¬µ±Á½¸ö¿ÉÄÜÒª×èÈûµÄʼþͬʱ³öÏÖʱ£¬¼´Á½¸öwait_event»òdown°ÚÔÚÒ»ÆðµÄʱºò£¬½«±äµÃ·Ç³£Î£ÏÕ£¬ËÀËøµÄ¿ÉÄÜÐԺܴó£¬Õâ¸öʱºòÎÒÃÇÒªÌرðÁôÒâËüÃǵijöÏÖ˳Ðò¡£µ±È»£¬ÎÒÃÇÓ¦¸Ã¾¡¿ÉÄܵرÜÃâÕâÖÖÇé¿öµÄ·¢Éú£¡
¡¡+»¹ÓÐÒ»¸öÓëÉ豸×èÈûÓë·Ç×èÈû·ÃÎÊϢϢÏà¹ØµÄÂÛÌ⣬¼´selectºÍpoll£¬selectºÍpollµÄ±¾ÖÊÒ»Ñù£¬Ç°ÕßÔÚBSD UnixÖÐÒýÈ룬ºóÕßÔÚSystem VÖÐÒýÈë¡£pollºÍselectÓÃÓÚ²éѯÉ豸µÄ״̬£¬ÒÔ±ãÓû§³ÌÐò»ñÖªÊÇ·ñÄܶÔÉ豸½øÐзÇ×èÈûµÄ·ÃÎÊ£¬ËüÃǶ¼ÐèÒªÉ豸Çý¶¯³ÌÐòÖеÄpollº¯ÊýÖ§³Ö¡£

¡¡¡¡Çý¶¯³ÌÐòÖÐpollº¯ÊýÖÐ×îÖ÷ÒªÓõ½µÄÒ»¸öAPIÊÇpoll_wait£¬ÆäÔ­ÐÍÈçÏ£º

[code]void poll_wait(struct file *filp, wait_queue_heat_t *queue, poll_table * wait);[/code]
¡¡¡¡poll_waitº¯ÊýËù×öµÄ¹¤×÷Êǰѵ±Ç°½ø³ÌÌí¼Óµ½wait²ÎÊýÖ¸¶¨µÄµÈ´ýÁÐ±í£¨poll_table£©ÖС£ÏÂÃæÎÒÃǸøglobalvarµÄÇý¶¯Ìí¼ÓÒ»¸öpollº¯Êý£º

[code]static unsigned int globalvar_poll(struct file *filp, poll_table *wait)
{
¡¡unsigned int mask = 0;

¡¡poll_wait(filp, &outq, wait);

¡¡//Êý¾ÝÊÇ·ñ¿É»ñµÃ£¿
¡¡if (flag != 0)
¡¡{
¡¡¡¡mask |= POLLIN | POLLRDNORM; //±êʾÊý¾Ý¿É»ñµÃ
¡¡}
¡¡return mask;
}[/code]
¡¡¡¡ÐèҪ˵Ã÷µÄÊÇ£¬poll_waitº¯Êý²¢²»×èÈû£¬³ÌÐòÖÐpoll_wait(filp, &outq, wait)Õâ¾ä»°µÄÒâ˼²¢²»ÊÇ˵һֱµÈ´ýoutqÐźÅÁ¿¿É»ñµÃ£¬ÕæÕýµÄ×èÈû¶¯×÷ÊÇÉϲãµÄselect/pollº¯ÊýÖÐÍê³ÉµÄ¡£select/poll»áÔÚÒ»¸öÑ­»·ÖжÔÿ¸öÐèÒª¼àÌýµÄÉ豸µ÷ÓÃËüÃÇ×Ô¼ºµÄpollÖ§³Öº¯ÊýÒÔʹµÃµ±Ç°½ø³Ì±»¼ÓÈë¸÷¸öÉ豸µÄµÈ´ýÁÐ±í¡£Èôµ±Ç°Ã»ÓÐÈκα»¼àÌýµÄÉ豸¾ÍÐ÷£¬ÔòÄں˽øÐе÷¶È£¨µ÷ÓÃschedule£©Èóöcpu½øÈë×èÈû״̬£¬schedule·µ»Øʱ½«ÔÙ´ÎÑ­»·¼ì²âÊÇ·ñÓвÙ×÷¿ÉÒÔ½øÐУ¬Èç´Ë·´¸´£»·ñÔò£¬ÈôÓÐÈÎÒâÒ»¸öÉ豸¾ÍÐ÷£¬select/poll¶¼Á¢¼´·µ»Ø¡£

¡¡¡¡ÎÒÃDZàдһ¸öÓû§Ì¬Ó¦ÓóÌÐòÀ´²âÊÔ¸ÄдºóµÄÇý¶¯¡£³ÌÐòÖÐÒªÓõ½BSD UnixÖÐÒýÈëµÄselectº¯Êý£¬ÆäÔ­ÐÍΪ£º

[code]int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);[/code]
¡¡¡¡ÆäÖÐreadfds¡¢writefds¡¢exceptfds·Ö±ðÊDZ»select()¼àÊӵĶÁ¡¢Ð´ºÍÒì³£´¦ÀíµÄÎļþÃèÊö·û¼¯ºÏ£¬numfdsµÄÖµÊÇÐèÒª¼ì²éµÄºÅÂë×î¸ßµÄÎļþÃèÊö·û¼Ó1¡£timeout²ÎÊýÊÇÒ»¸öÖ¸Ïòstruct timevalÀàÐ͵ÄÖ¸Õ룬Ëü¿ÉÒÔʹselect()Ôڵȴýtimeoutʱ¼äºóÈôûÓÐÎļþÃèÊö·û×¼±¸ºÃÔò·µ»Ø¡£struct timevalÊý¾Ý½á¹¹Îª£º

[code]struct timeval
{
¡¡¡¡int tv_sec; /* seconds */
¡¡¡¡int tv_usec; /* microseconds */
};[/code]
¡¡¡¡³ý´ËÖ®Í⣬ÎÒÃÇ»¹½«Ê¹ÓÃÏÂÁÐAPI£º

¡¡¡¡FD_ZERO(fd_set *set)¡ª¡ªÇå³ýÒ»¸öÎļþÃèÊö·û¼¯£»
¡¡¡¡FD_SET(int fd,fd_set *set)¡ª¡ª½«Ò»¸öÎļþÃèÊö·û¼ÓÈëÎļþÃèÊö·û¼¯ÖУ»
¡¡¡¡FD_CLR(int fd,fd_set *set)¡ª¡ª½«Ò»¸öÎļþÃèÊö·û´ÓÎļþÃèÊö·û¼¯ÖÐÇå³ý£»
¡¡¡¡FD_ISSET(int fd,fd_set *set)¡ª¡ªÅжÏÎļþÃèÊö·ûÊÇ·ñ±»ÖÃλ¡£

¡¡¡¡ÏÂÃæµÄÓû§Ì¬²âÊÔ³ÌÐòµÈ´ý/dev/globalvar¿É¶Á£¬µ«ÊÇÉèÖÃÁË5ÃëµÄµÈ´ý³¬Ê±£¬Èô³¬¹ý5ÃëÈÔȻûÓÐÊý¾Ý¿É¶Á£¬ÔòÊä³ö"No data within 5 seconds"£º

[code]#include
#include
#include
#include
#include
#include
#include

main()
{
¡¡int fd, num;
¡¡fd_set rfds;
¡¡struct timeval tv;

¡¡fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR);
¡¡if (fd != - 1)
¡¡{
¡¡¡¡while (1)
¡¡¡¡{
¡¡¡¡¡¡//²é¿´globalvarÊÇ·ñÓÐÊäÈë
¡¡¡¡¡¡FD_ZERO(&rfds);
¡¡¡¡¡¡FD_SET(fd, &rfds);
¡¡¡¡¡¡//ÉèÖó¬Ê±Ê±¼äΪ5s
¡¡¡¡¡¡tv.tv_sec = 5;
¡¡¡¡¡¡tv.tv_usec = 0;
¡¡¡¡¡¡select(fd + 1, &rfds, NULL, NULL, &tv);

¡¡¡¡¡¡//Êý¾ÝÊÇ·ñ¿É»ñµÃ£¿
¡¡¡¡¡¡if (FD_ISSET(fd, &rfds))
¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡read(fd, &num, sizeof(int));
¡¡¡¡¡¡¡¡printf("The globalvar is %d\n", num);

¡¡¡¡¡¡¡¡//ÊäÈëΪ0£¬Í˳ö
¡¡¡¡¡¡¡¡if (num == 0)
¡¡¡¡¡¡¡¡{
¡¡¡¡¡¡¡¡¡¡close(fd);
¡¡¡¡¡¡¡¡¡¡break;
¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡}
¡¡¡¡¡¡else
¡¡¡¡¡¡¡¡printf("No data within 5 seconds.\n");
¡¡¡¡}
¡¡}
¡¡else
¡¡{
¡¡¡¡printf("device open failure\n");
¡¡}
}[/code]
¡¡¡¡¿ªÁ½¸öÖնˣ¬·Ö±ðÔËÐгÌÐò£ºÒ»¸ö¶Ôglobalvar½øÐÐд£¬Ò»¸öÓÃÉÏÊö³ÌÐò¶Ôglobalvar½øÐжÁ¡£µ±ÎÒÃÇÔÚдÖն˸øglobalvarÊäÈëÒ»¸öÖµºó£¬¶ÁÖÕ¶ËÁ¢¼´¾ÍÄÜÊä³ö¸ÃÖµ£¬µ±ÎÒÃÇÁ¬Ðø5ÃëûÓÐÊäÈëʱ£¬"No data within 5 seconds"ÔÚ¶ÁÖն˱»Êä³ö£¬ÈçÏÂͼ£º

[align=center][/align]
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ