内核空间和用户空间有什么区别?内核空间,内核线程,内核进程和内核堆栈是否意味着相同的事情?另外,为什么我们需要这种区别?
我正在阅读linux内核,我发现了很多像这样的宏:
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
Run Code Online (Sandbox Code Playgroud)
为什么他们使用这个而不是简单地在{}中定义它?
任何人都可以解释我,
IOCTL?IOCTL?我已经google了一下,发现大多数人都主张使用kmalloc,因为你可以保证获得连续的物理内存块.但是,kmalloc如果找不到您想要的连续物理块,它似乎也会失败.
拥有一块连续的内存块有什么好处?具体来说,为什么我需要在系统调用中拥有连续的物理内存块?我有什么理由不能使用吗?
最后,如果我在处理系统调用期间分配内存,我应该指定吗?系统调用是在原子上下文中执行的吗?vmallocGFP_ATOMIC
GFP_ATOMIC
分配是高优先级的,不会睡眠.这是在中断处理程序,下半部分和其他无法睡眠的情况下使用的标志.
GFP_KERNEL这是正常分配,可能会阻止.这是在安全睡眠时在进程上下文代码中使用的标志.
如果指向文件同时获得Linux上的打开文件句柄会发生什么:
为什么我问这样的问题:我使用的是热插拔硬件(如USB设备等).可能发生的是,设备(及其/ dev /文件)被用户或另一个Gremlin重新附加.
处理这个问题的最佳做法是什么?
我们希望将服务器上的操作系统从Ubuntu 10.04 LTS升级到Ubuntu 12.04 LTS.不幸的是,似乎运行已经变为可运行的线程的延迟从2.6内核到3.2内核显着增加.事实上,我们得到的延迟数字很难相信.
让我对测试更加具体.我们有一个运行两个线程的程序.第一个线程获取当前时间(使用RDTSC以滴答为单位),然后每秒发送一次条件变量.第二个线程等待条件变量并在发出信号时唤醒.然后它获取当前时间(使用RDTSC以滴答为单位).计算第二个线程中的时间与第一个线程中的时间之间的差异,并在控制台上显示.在此之后,第二个线程再次等待条件变量.大约第二次通过后,第一个线程将再次发出信号.
因此,简而言之,我们得到一个线程,通过条件可变延迟测量一次一次地进行线程通信.
在内核2.6.32中,这种延迟大约为2.8-3.5 us,这是合理的.在内核3.2.0中,这种延迟已经增加到大约40-100 us.我已经排除了两台主机之间硬件的任何差异.它们运行在相同的硬件上(双插槽X5687 {Westmere-EP}处理器,运行频率为3.6 GHz,具有超线程,speedtep和所有C状态关闭).测试应用程序更改线程的亲和力以在同一套接字的独立物理核心上运行它们(即,第一个线程在Core 0上运行,第二个线程在Core 1上运行),因此没有线程的弹跳套接字之间的核心或弹跳/通信.
两台主机之间的唯一区别是,一台运行Ubuntu 10.04 LTS,内核为2.6.32-28(快速上下文切换盒),另一台运行最新的Ubuntu 12.04 LTS,内核为3.2.0-23(缓慢的上下文)开关盒).所有BIOS设置和硬件都相同.
内核是否有任何变化可以解释线程被安排运行多长时间的这种荒谬的减速?
更新: 如果您想在主机和Linux版本上运行测试,我已将代码发布到pastebin供您阅读.编译:
g++ -O3 -o test_latency test_latency.cpp -lpthread
Run Code Online (Sandbox Code Playgroud)
运行(假设您至少有一个双核盒子):
./test_latency 0 1 # Thread 1 on Core 0 and Thread 2 on Core 1
Run Code Online (Sandbox Code Playgroud)
更新2:经过大量内核参数搜索,内核更改和个人研究的帖子后,我已经找出了问题所在并已发布解决方案作为这个问题的答案.
我收到mongodb关于THP的以下警告
2015-03-06T21:01:15.526-0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-03-06T21:01:15.526-0800 I CONTROL [initandlisten] ** We suggest setting it to 'never'
Run Code Online (Sandbox Code Playgroud)
但我确实设法手动关闭了THP
frederick@UbuntuVirtual:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
frederick@UbuntuVirtual:~$ cat /sys/kernel/mm/transparent_hugepage/defrag
always madvise [never]
Run Code Online (Sandbox Code Playgroud)
我加入的伎俩transparent_hugepage=never,以GRUB_CMDLINE_LINUX_DEFAULT中/etc/default/grub和添加
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
Run Code Online (Sandbox Code Playgroud)
至 /etc/rc.local
我怎么能避免警告?
内核堆栈和用户堆栈之间有什么区别?为什么要使用内核堆栈?如果在ISR中声明了局部变量,那么它将被存储在哪里?每个进程都有自己的内核堆栈吗?然后这两个堆栈之间的进程如何协调?
是否有可能在Linux中"休眠"一个进程?就像笔记本电脑中的"休眠"一样,我会将进程使用的所有内存写入磁盘,释放内存.然后,我可以"恢复过程",即从内存中读取所有数据并将其放回RAM中,我可以继续我的过程吗?
我有一个与Linux中的线程实现相关的查询.
Linux没有明确的线程支持.在用户空间中,我们可能使用线程库(如NPTL)来创建线程.现在,如果我们使用NPTL,它支持1:1映射.
内核将使用该clone()函数来实现线程.
假设我创建了4个线程.那意味着:
task_struct.task_struct,将根据克隆的参数提供共享资源(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND).现在我有以下查询:
linux-kernel ×10
linux ×6
c ×2
kernel ×2
driver ×1
file ×1
file-io ×1
ioctl ×1
kmalloc ×1
macros ×1
mongodb ×1
pid ×1
terminology ×1
ubuntu-12.04 ×1
vmalloc ×1