如果你走入我们的内核之旅网站http://www.kerneltravel.net/ ,静下心阅读并动手实践,或许,流逝的时间,让你手捧沉甸甸的果实。 欢迎在讨论区提问。 如果你希望有即时的讨论,欢迎到西邮Linux兴趣小组:http://groups.google.com/group/xiyouLinux

管理 给我的留言

毕业的学生 留言于2008-06-26 17:01:31
陈老师您好,我是一个大四即将毕业的学生(或许说是一个已经毕了业的学生,因为昨天刚完成答辨)。

这是我第一次上您的博客,刚进来的时候就看到“周立功杯”C语言大赛获奖的贴子,我真的很羡慕您的学生,如果我们学校能有您这样一个老师就好了,我也就能早一些接触Linux。

现在虽然我已经工作了,但我感觉自己还是差很多,以后有问题希望陈老师能帮助解决一下!
puzhengcai 留言于2008-06-21 10:49:34
我觉得陈老师是我从网上认识的一位很专业敬业的老师,须然您不认识我,我也不是您的学生,我只是一位自由软件爱好者。我平时的兴趣是学习GNU/Linux系统,很爱它。我希陈老师能借住您的知识和经验写一篇LINUX学习指南之类的文章来指导我们这些学习起来也许有点盲目或效率很低的爱好者。最后谢谢您,我的邮箱是:puzhengcai@gmail.com :)希望能和您多多交流
仰空冥思 陈莉君 留言于2008-06-14 12:01:37
回复 maigo:
IPC是用户级进程间的通信方式,对基于SMP的内核而言,进程在哪个CPU上运行是调度程序的事。从用户级来看,不管是单CPU还是SMP,进程间通信应当依然是IPC形式。
maigo 留言于2008-06-11 10:49:35
陈老师,您好!
    一直在关注您的文章!给了我不少的帮助
最近我在学习关于Linux SMP方面的东西,请问在SMP系统中不同处理器上的进程是怎样通信的?
还是按照原来的IPC机制么?我在内核代码smp.c中看到有inter-processor interrupt相关的代码,又是用来做什么的呢?
    谢谢!
Guest 留言于2008-06-03 11:15:41
陈老师好!
    看了您在“内核之旅”里的文章,最后找到这儿来了。感谢您对这们这些kernel初学者的贡献。
木天 留言于2008-06-01 16:02:30
既然
__sighandler_t是函数指针类型,它的定义为:
typedef void (*__sighandler_t) (int);


#define SIG_IGN ( (__sighandler_t)1)    /* ignore signal */
整数1就应该被转化为一个函数指针了。

这么做的目的应该是为了后面程序使用该标志(“1”)时类型匹配。

#define SIG_DFL    ((__sighandler_t)0)    /* 缺省的信号处理*/
#define SIG_IGN    ((__sighandler_t)1)     /*忽略这个信号*/

比如程序传来一个信号处理函数,handler,我们要判断这个函数是某个特定标志还是真实的函数,
if(handler == SIG_IGN)
{
        ……
}
else
{
        ……
}
这就不会引起编译器的类型不符警告。

gdb的用法我也不太熟,就不知道了。但它的值应该还是1,只不过类型是 __sighandler_t 型罢了。
七度黑光 helight 留言于2008-06-01 12:51:31
其实经我测试,SIG_IGN的值还是1,无论是整型,还是字符型。
char k=(__sighandler_t)1;
这样的话,可以在gdb先看到,但是直接看SIG_IGN不行。
Guest 留言于2008-05-30 12:07:03
陈老师,您这里真是车水马龙呀!
呵呵,请教大家一个问题:
#define SIG_IGN ( (__sighandler_t)1)    /* ignore signal */
整数1被强制转化成了什么?
能不能用gdb查看((__sighandler_t)1)的值?

__sighandler_t是函数指针类型,它的定义为:
typedef void (*__sighandler_t) (int);
Guest 留言于2008-05-29 13:07:06
陈老师,您好,
我在一家IT公司主管开发工作,偶尔发现您写的深入分析linux内核。虽然我对linux的了解不多,但觉得您写的内容真的很精彩。有机会请您到我们公司来给开发员工培训。
我的邮件地址:ligang@sunniwell.com.cn
Nancy 留言于2008-05-23 17:35:54
期望陈老师能写一些关于如何进行linux内核性能分析的文章,谢谢!
仰空冥思 陈莉君 留言于2008-05-19 15:03:34
回复 blueiris :2.6内核已经实现了实时,你可以阅读其代码,参考其设计思路。
blueiris blueiris 留言于2008-05-18 21:04:23
陈老师您好:
最近导师给我个写论文的方向是关于linux实时改进的。不知道陈老师有什么的好的建议
bin 留言于2008-05-05 11:42:12
To logic :
你好,我也正在做毕业设计,题目是:linux下的同步机制,也正在调试那个程序,不知道你的问题有没有解决?
方便的话,可否留下联系方式?
希望可以一起讨论,一齐进步!
我的邮箱:xdd123www@gmail.com
仰空冥思 陈莉君 留言于2008-05-04 13:07:48
<深入理解Linux内核》第一版就没有网络这一章,当时作者说这部分内容太多,足以写一本书,第二版中加了网络,但讲的也比较基本。估计第三版时,又回到第一版时的想法了。
Guest 留言于2008-05-03 10:33:52
陈老师,您好!我刚刚买来了深入理解linux内核第三版,为什么第三版中把第二版的网络那一章省掉了?
陈老师 留言于2008-05-02 07:20:57
回复logic ,在退出函数中加printk语句,看看死机前执行到哪一句
logic 留言于2008-04-30 12:29:51
陈老师您好,我是一名大四学生,在做linux的实验演示系统。在实验中我选了您的《linux操作系统原理与应用》一书中的“并发控制”实例(p157),其中的sharelist.c在模块生成时很正确,执行也很顺利,但在卸载模块的时候就死机了。感觉应该没有问题的呀,可是就是解决不了,希望老师指导。我的内核版本是(2.4.36)
代码如下:
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#if defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
#include <linux/signal.h>
#include <asm/semaphore.h>
#include <asm/smplock.h>
#include <linux/list.h>
#include <linux/string.h>
#include <asm/errno.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <asm/atomic.h>

//thread number
#define NTHREADS 500
struct my_struct{
       struct list_head list;
       int id;
       int pid;
};
wait_queue_head_t queue;
//for tq_timer
struct tq_struct task;
//for keventd
struct tq_struct tq;
//our sharelist head
static LIST_HEAD(mine);
static unsigned int list_len = 0;
static int timer_over = 0;
//for synchronization of kernel thread to continue runing
static DECLARE_MUTEX(sem);
//for protecting our list
static spinlock_t my_lock=SPIN_LOCK_UNLOCKED;
//for add in atomic way
static atomic_t my_count=ATOMIC_INIT(0);

/* it build a kernel thread */
int sharelist(void*);
static void kthread_launcher(void *data)
{
  kernel_thread((int (*)(void *))sharelist, NULL, 0);
  up(&sem);  
}

/* the kernel thread , which add node to list */
int sharelist(void * data)
{
  int i;  
  struct my_struct *p;
  if((p=kmalloc(sizeof(struct my_struct),GFP_KERNEL))==NULL)
  return -ENOMEM;
  p->id=atomic_read(&my_count);
  atomic_inc(&my_count);
  p->pid=current->pid;
  spin_lock_bh(&my_lock);
  if(list_len<400)
     {
     list_add(&p->list,&mine);
     list_len++;
     printk("ADD:%d\t",p->id);
   //printk("List len = %d\n",list_len);
    }
    else
    {   
     struct my_struct *my = NULL;     
     my=list_entry(mine.prev,struct my_struct,list);
     list_del(mine.prev);
     list_len--;
     printk("DEL:%d\t",my->id);
     kfree(my);            
    }
    spin_unlock_bh(&my_lock);
  return 0;
}

//it call keventd to run kernel thread
void start_kthread()
{
  tq.sync=0;
  INIT_LIST_HEAD(&tq.list);
  tq.routine=kthread_launcher;
  tq.data=NULL;
  schedule_task(&tq);
  down(&sem);  
}

//static int count =0;
int qt_task(){
       
if (timer_over == 0)
{       
// if(++count<500)
// {
  if(!list_empty(&mine))
   {               
    struct my_struct *i;
    i=list_entry(mine.next,struct my_struct,list);
    list_del(mine.next);
    list_len--;
    printk("del:%d\t",i->id);
    kfree(i);
   }//else printk(" empty now \n");
  queue_task(&task,&tq_timer);
// }
}
return 0;
}

static int  __init share_init(void)
{
  init_waitqueue_head(&queue);
  task.routine=(void*)qt_task;
  task.data=NULL;
  queue_task(&task,&tq_timer);
  int i;
  for(i=0;i<NTHREADS;i++)
     {          
  //   interruptible_sleep_on_timeout(&queue,HZ/1024);
       start_kthread();      
     }  
return 0;
}


static void __exit share_exit(void)
{
   /* print to dmesg */
    printk("Exiting \n");
    struct list_head *p=NULL;
    struct my_struct *my=NULL;
    // down(&sem);
    spin_lock_bh(&my_lock);
    list_for_each(p,&mine)
    {
     my=list_entry(p,struct my_struct,list);
     list_del(p);
     kill_proc(my->pid,SIGKILL,1);
     printk("node is:%d\t",my->id);
     kfree(my);
     timer_over=1;
    }
    //up(&sem);
    spin_unlock_bh(&my_lock);
    printk("Over \n");
    //sleep(100);
    interruptible_sleep_on_timeout(&queue,HZ*10);
    kill_proc(2,SIGCHLD,1);
    return ;
}




module_init(share_init);/**<\brief on loading this file, call audit_init*/
module_exit(share_exit);/**<\brief on finishing with this file, call audit_exit*/
XCL 留言于2008-04-26 17:49:13
悄悄话,只给空间主人查看...
MCY 留言于2008-04-16 16:28:00
陈老师,你好!
我是98年毕业于西邮,计通专业的学生。
今天看到你的博客真是太好了。
实在后悔当初在这方面学的太少了,现在的工作整天在用这方面的知识。
我会逐渐学习你的文章的。
linuxer 留言于2008-04-11 20:30:50
陈老师问您一个问题:

#include "stdio.h"
main()
{
        char ps[]="Hello!",*p=ps;
        char pt[]="He is a worker!";
        printf("%p\n",ps);
        printf("%s\n",ps);
        printf("%p\n",pt);
        printf("%s\n",pt);
                                                                                
        for(p=ps;p<ps+11;p++)   *p='N';        //越界
        printf("%p\n",ps);
        printf("%s\n",ps);
        printf("%p\n",pt);                       
        printf("%s\n",pt);
                                                                                
        scanf("%s",ps);                        //输入字符串长度超过6则越界
        printf("%p\n",pt);
        printf("%s\n",pt);
}

就上面一段代码在windows下的wintc和linux下gcc运行结果是不一样的,我想问的是,在刚开始定义的两个数组在linux下给它们分配的内存是不是连续的?还有linux是怎么处理数组越界的?
留言两句

  

(可选)

Open Toolbar