linux生产者和消费者步机制,Linux内核中实现生产者与消费者(避免无效唤醒)【转】...

本文关注的重点是,避免内核线程的无效唤醒,并且主要是关注消费者线程的设计。

因此,为了省事,这里关与生产者,消费者本身的处理流程可能不够严密。

1. 生产者

一个内核线程,每生产一个商品后,就唤醒消费者,然后自己睡眠1秒钟。

2. 消费者

一个内核线程,每当被唤醒后,就消费商品,然后进入睡眠。

对于消费者线程的这种设计,有几个好处:响应快,平时不占任何cpu。

但这种设计有一点要注意,那就是要避免线程的无效唤醒。如何实现,看看消费者线程的代码就知道了。

/*

* kernel programming test code

*

* Copyright (C) 2014 Sun Mingbao

* Dual licensed under the MIT and/or GPL licenses.

*

*/

#include

#include

#include

#include

#include

#include

#include

MODULE_AUTHOR("Sun Mingbao ");

MODULE_DESCRIPTION("kernel programming test code");

MODULE_VERSION("1.0");

MODULE_LICENSE("Dual MIT/GPL");

#define  MODULE_NAME    "test"

#define    WRITE_CONSOLE(fmt, args...) \

do \

{ \

printk(KERN_ALERT fmt,##args); \

} while (0)

#define    DBG_PRINT(fmt, args...) \

do \

{ \

WRITE_CONSOLE(MODULE_NAME"_DBG:%s(%d)-%s:\n"fmt"\n", __FILE__,__LINE__,__FUNCTION__,##args); \

} while (0)

static struct task_struct *consumer_thread;

static struct task_struct *producer_thread;

static u32 cnt_consumer, cnt_producer;

static int has_something_to_consume = 0;

static void consume()

{

has_something_to_consume = 0;

cnt_consumer++;

}

static void produce()

{

has_something_to_consume = 1;

cnt_producer++;

}

static int consumer_thread_func(void * data)

{

while (!kthread_should_stop())

{

if (has_something_to_consume)

{

consume();

}

set_current_state(TASK_INTERRUPTIBLE);

if (has_something_to_consume)

{

set_current_state(TASK_RUNNING);

continue;

}

schedule();

}

if (has_something_to_consume)

{

consume();

}

}

static int producer_thread_func(void * data)

{

while (!kthread_should_stop())

{

produce();

if (consumer_thread->state & TASK_INTERRUPTIBLE)

{

wake_up_process(consumer_thread);

}

set_current_state(TASK_INTERRUPTIBLE);

schedule_timeout(HZ);

}

}

static int __init create_threads(void)

{

consumer_thread=kthread_run(consumer_thread_func, NULL, "consumer_thread");

producer_thread=kthread_run(producer_thread_func, NULL, "producer_thread");

return 0;

}

static struct proc_dir_entry *my_proc_dir;

static int misc_info_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data)

{

int ret;

static char proc_file_contents[128];

static int proc_file_len = 0;

if (0==offset || 0==proc_file_len)

{

proc_file_len=sprintf(proc_file_contents, "cnt_producer:%u\n""cnt_consumer:%u\n", cnt_producer, cnt_consumer);

}

ret=snprintf(buffer, length, "%s", proc_file_contents+offset);

if(ret+offset==proc_file_len)

*eof = 1;

return ret;

}

static int __init create_my_proc_entries(void)

{

my_proc_dir = proc_mkdir(MODULE_NAME, NULL);

create_proc_read_entry("misc_info"

,0

, my_proc_dir

, misc_info_read_proc

, NULL);

return 0;

}

static void __exit remove_my_proc_entries(void)

{

remove_proc_entry("misc_info", my_proc_dir);

remove_proc_entry(MODULE_NAME, NULL);

}

static int __init test_init(void)

{

int retval;

DBG_PRINT("start");

retval=create_threads();

if (retval < 0)

{

goto EXIT;

}

create_my_proc_entries();

DBG_PRINT("start succeed");

EXIT:

return retval;

}

static void __exit stop_threads(void)

{

kthread_stop(consumer_thread);

kthread_stop(producer_thread);

}

static void __exit test_exit(void)

{

DBG_PRINT("quit");

remove_my_proc_entries();

stop_threads();

}

module_init(test_init);

module_exit(test_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值