linux内核栈,内核同步,用户空间线程同步
来源:互联网 发布:折八百淘宝商城女装 编辑:程序博客网 时间:2024/06/05 03:29
在论坛上浏览到一个帖子,是说内核栈的问题的,一时却感到有点陌生了,下面总结一下
http://topic.csdn.net/u/20121101/10/86479004-2f2c-491c-bc43-03cc0e087588.html?69419
1.每当创建一个进程(主线程),用户线程,内核线程时,内核都会给这个进程或线程动态创建一个内核栈,在内核空间,换存在cache中。内核栈里有个thread_info指针,指向task_struct结构体(cpu根据这个来调度,所以可以实现调度的基本单位是线程)。
2.进程用户栈:创建一个用户进程(主线程)时,需要创建一个mm_struct,使其task_struct中的mm指针指向此mm_struct
3.用户线程和其他线程共享用户栈“:创建一个用户线程时,使其task_struct中的mm指针指向一个已存在的mm_struct。这些线程共用一个进程地址空间。
4.内核线程没有用户栈:创建一个内核线程时,使其task_struct中的mm指针为空。
5.对于进程地址空间,用户栈存放局部变量等东东,数据段.data存放全局变量和static变量(static局部变量)
6.对于内核地址空间(0xc000 0000以上的),其是不是也分为数据段代码段呢?是不是数据段也存放着内核的全局变量和statci变量呢?
有一点可以知道,内核空间有n多个内核栈,有多少线程就有多少内核栈,但每个栈都很小(不像进程空间的用户栈,一个进程只有一个用户栈,但很大)
7.从用户态进入内核是什么意思?
先看 进程上下文 中断上下文 / 用户空间 内核空间
比如一个进程在他的地址空间(0xc000 0000 以下)里面玩的好好的,突然要调用一个函数(系统调用),而这个函数位于地址0xc666 6666(整个内核地址空间即0xc000 0000以上有什么函数和符号,其地址可以理解为都是已经确定好的),于是就要跑到0xc666 6666地址去执行,此时算是进入内核态了。在执行0xc666 6666这个函数时,函数里面的局部变量需要保存在这个进程的对应的内核栈里面,内核栈<8KB,不要使用过大的变量(如大的数组),否则溢出死机。
驱动里的全局变量,局部变量,static局部变量放在哪里了?
这些变量可以被不同的应用程序共享吗?
如下:
kbuf的地址每次都不一样,可能位于内核的某个slab空间里面(不单独为某个进程所有)
局部变量b位于进程的内核栈里面,0xcd439f4c,每个进程都有独立的b
static 局部变量c变成4说明可以被共享不随着进程的消失而销毁,c应该不是保存在进程的内核栈里面,因为进程内核栈随着进程的消失会销毁
全部变量a变成3说明可以被共享,a也应该不是保存在进程的内核栈里面,
那么a和c保存在哪里呢?
a和c的地址位于0xc000 0000 以下,,内核里的全局变量怎么跑到用户空间了?
看一下模块加载到的地址0xbf024000,也是0xc000 0000以下,和a,c的地址很接近,似乎有点关系
待续
51的局部变量和全局变量:
cpu arch之risc, cisc ,von-neumann,harvard ,modified harvard
http://blog.csdn.net/zzran/article/details/8830213
http://topic.csdn.net/u/20121101/10/86479004-2f2c-491c-bc43-03cc0e087588.html?69419
1.内核栈
1.每当创建一个进程(主线程),用户线程,内核线程时,内核都会给这个进程或线程动态创建一个内核栈,在内核空间,换存在cache中。内核栈里有个thread_info指针,指向task_struct结构体(cpu根据这个来调度,所以可以实现调度的基本单位是线程)。
2.进程用户栈:创建一个用户进程(主线程)时,需要创建一个mm_struct,使其task_struct中的mm指针指向此mm_struct
3.用户线程和其他线程共享用户栈“:创建一个用户线程时,使其task_struct中的mm指针指向一个已存在的mm_struct。这些线程共用一个进程地址空间。
4.内核线程没有用户栈:创建一个内核线程时,使其task_struct中的mm指针为空。
5.对于进程地址空间,用户栈存放局部变量等东东,数据段.data存放全局变量和static变量(static局部变量)
6.对于内核地址空间(0xc000 0000以上的),其是不是也分为数据段代码段呢?是不是数据段也存放着内核的全局变量和statci变量呢?
有一点可以知道,内核空间有n多个内核栈,有多少线程就有多少内核栈,但每个栈都很小(不像进程空间的用户栈,一个进程只有一个用户栈,但很大)
7.从用户态进入内核是什么意思?
先看 进程上下文 中断上下文 / 用户空间 内核空间
比如一个进程在他的地址空间(0xc000 0000 以下)里面玩的好好的,突然要调用一个函数(系统调用),而这个函数位于地址0xc666 6666(整个内核地址空间即0xc000 0000以上有什么函数和符号,其地址可以理解为都是已经确定好的),于是就要跑到0xc666 6666地址去执行,此时算是进入内核态了。在执行0xc666 6666这个函数时,函数里面的局部变量需要保存在这个进程的对应的内核栈里面,内核栈<8KB,不要使用过大的变量(如大的数组),否则溢出死机。
驱动里的全局变量,局部变量,static局部变量放在哪里了?
这些变量可以被不同的应用程序共享吗?
如下:
/********************************base.c**************/ #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/time.h> #include <linux/timer.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/gpio.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #define DEBUG #ifdef DEBUG #define DBG(...) printk(" DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); printk(__VA_ARGS__) #else #define DBG(...) #endif #define DEVICE_NAME "misc_test_dev" int ret;#define NUM_BYTES 32int a=1;ssize_t misc_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { return 0; //return the bytes quantity have copied} ssize_t misc_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { char *kbuf=kmalloc(1,GFP_KERNEL);*kbuf++;printk("*kbuf=%d,kbuf=0x%x\n",*kbuf,kbuf);int b=2;b++;printk("b=%d,&b=0x%x\n",b,&b);static int c=2;c++;printk("c=%d,&c=0x%x\n",c,&c);a++;printk("a=%d,&a=0x%x\n",a,&a); return count ; //return the bytes quantity have copied} static int misc_release(struct inode *inode, struct file *filp) {DBG("release \n"); return 0; } static int misc_open(struct inode *inode, struct file *filp) { DBG("open \n"); return 0; } static struct file_operations dev_fops = { .owner = THIS_MODULE, .open = misc_open, .read = misc_read, .write = misc_write, .release= misc_release, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops, }; static int __init dev_init(void) { int ret; ret = misc_register(&misc); DBG (DEVICE_NAME"\tinit\n"); return ret; } static void __exit dev_exit(void) { DBG (DEVICE_NAME"\texit\n"); misc_deregister(&misc); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Song.");
/********************************readtest.c**************/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <linux/fs.h> #include <errno.h> #include <string.h> #define DEBUG#ifdef DEBUG #define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__) #else #define DBG(...) #endif #define NUM_BYTES 32int main(int argc,char* argv[]) { int fd = open(argv[1], 0); if (fd < 0) { perror("open file "); return 1; } char buf; int len = read(fd, &buf, 1); pause();close(fd); }在tiny6410上测试:
[root@FriendlyARM /]# insmod base.ko DBG(/work/linux/test/base.c, dev_init(), 98): misc_test_dev init[root@FriendlyARM /]# lsmod base 1861 0 - Live 0xbf024000//模块所在地址fa_cpu_pfn 715 0 - Live 0xbf000000 (P)[root@FriendlyARM /]# [root@FriendlyARM /]# ./readtest /dev/misc_test_dev DBG(/work/linux/test/base.c, misc_open(), 75): open *kbuf=70,kbuf=0xcd654901b=3,&b=0xcd439f4cc=3,&c=0xbf0242aca=2,&a=0xbf0242b0^C DBG(/work/linux/test/base.c, misc_release(), 69): release [root@FriendlyARM /]# //ctrl+c断掉,然后再次执行一次[root@FriendlyARM /]# ./readtest /dev/misc_test_dev DBG(/work/linux/test/base.c, misc_open(), 75): open *kbuf=76,kbuf=0xcd6546a1b=3,&b=0xcd439f4cc=4,&c=0xbf0242ac a=3,&a=0xbf0242b0 ^C DBG(/work/linux/test/base.c, misc_release(), 69): release [root@FriendlyARM /]#从上面的例子可以看出
kbuf的地址每次都不一样,可能位于内核的某个slab空间里面(不单独为某个进程所有)
局部变量b位于进程的内核栈里面,0xcd439f4c,每个进程都有独立的b
static 局部变量c变成4说明可以被共享不随着进程的消失而销毁,c应该不是保存在进程的内核栈里面,因为进程内核栈随着进程的消失会销毁
全部变量a变成3说明可以被共享,a也应该不是保存在进程的内核栈里面,
那么a和c保存在哪里呢?
a和c的地址位于0xc000 0000 以下,,内核里的全局变量怎么跑到用户空间了?
看一下模块加载到的地址0xbf024000,也是0xc000 0000以下,和a,c的地址很接近,似乎有点关系
待续
51的局部变量和全局变量:
cpu arch之risc, cisc ,von-neumann,harvard ,modified harvard
2.用户空间同步
http://blog.csdn.net/zzran/article/details/8830213#include<stdio.h>#include<sys/types.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>#define DEBUG#ifdef DEBUG#define DBG(...) printf("%s(),%d:", __FUNCTION__,__LINE__); printf(__VA_ARGS__)#else#define DBG(...) #endifpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;int count = 0;void *decrement(void *arg) { DBG("count=%d\n",count); pthread_mutex_lock(&mutex); DBG("count=%d\n",count); if (count == 0) pthread_cond_wait(&cond, &mutex); count--; DBG("count=%d.\n",count); pthread_mutex_unlock(&mutex);DBG("count=%d.\n",count); return NULL;}void *increment(void *arg) { DBG("count=%d\n",count); pthread_mutex_lock(&mutex); DBG("count=%d\n",count); count++; DBG("count=%d\n",count); if (count != 0) pthread_cond_signal(&cond); DBG("count=%d\n",count); pthread_mutex_unlock(&mutex);DBG("count=%d\n",count); return NULL;}int main(int argc, char *argv[]) { pthread_t tid_in, tid_de; pthread_create(&tid_de, NULL, (void*)decrement, NULL); sleep(2); pthread_create(&tid_in, NULL, (void*)increment, NULL); sleep(5); pthread_join(tid_de, NULL); pthread_join(tid_in, NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0;}
等待线程:
pthread_cond_wait前使用pthread_mutex_lock先加锁
pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活
pthread_cond_wait被激活后会再自动加锁
pthread_cond_wait返回之后需要使用pthread_mutex_unlock释放锁
激活线程:
pthread_cond_signal前使用pthread_mutex_lock加锁(和等待线程用同一个锁)
pthread_cond_signal发送信号
pthread_cond_signal返回之后需要使用pthread_mutex_unlock释放锁
- linux内核栈,内核同步,用户空间线程同步
- linux内核栈,内核同步,用户空间线程同步
- Linux 内核线程间同步
- Linux内核同步,进程,线程同步
- Linux内核同步,进程,线程同步
- Linux内核同步/进程/线程同步
- Linux内核同步,进程,线程同步
- Linux内核同步,进程,线程同步
- linux内核-内核同步
- Linux内核同步,进程,线程同步各种方法
- linux内核笔记-内核同步
- linux的内核同步
- linux内核同步
- Linux内核同步
- Linux内核同步1
- Linux内核同步2
- linux内核同步方式
- Linux 内核同步机制
- SetCapture捕获鼠标 ,转换获取的坐标
- Unicode下的CString与String之间的相互转换
- 智能机成本跌穿200元
- 月初伤感日志巨献:爱流逝了,我依旧等你
- 面向切面(AOP)"与"面向对象(OOP)
- linux内核栈,内核同步,用户空间线程同步
- Android TextView的各种属性
- C#时间转JS时间格式
- Android View Animation
- hdu - 4343 - Interval query - dp(贪心)
- 简单FTP(vsftp)架设
- 苹果默认字体
- 1000以内所有偶数和!
- androidx线程详解