Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55741
  • 博文数量: 47
  • 博客积分: 2095
  • 博客等级: 大尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-01 18:42
文章分类

全部博文(47)

文章存档

2011年(1)

2008年(46)

我的朋友

分类: LINUX

2008-04-26 15:37:40

前面学习了进程和线程的创建都是通过clone()系统调用来完成的,具体Linux如何做的呢:
1 先看fork:

~/code$ cat fork.c

#include
#include

int main()
{
       pid_t pid;
        if( (pid = fork()) == 0 ) {
                getpid();
                getppid();
                return 0;
        }
        waitpid(pid, NULL, NULL);
        return 0;
}

fork创建的子进程里查看了本进程的pid和ppid(父进程id)
~/code$ gcc -o fork_test fork.c
~/code$ strace  -f ./fork_test
execve("./fork_test", ["./fork_test"], [/* 38 vars */]) = 0
brk(0)                                  = 0x804a000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5e000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=44092, ...}) = 0
mmap2(NULL, 44092, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f53000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260a\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1339816, ...}) = 0
mmap2(NULL, 1349136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e09000
mmap2(0xb7f4d000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x143) = 0xb7f4d000
mmap2(0xb7f50000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f50000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e08000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e086b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7f4d000, 4096, PROT_READ)   = 0
munmap(0xb7f53000, 44092)               = 0
clone(Process 12901 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e086f8) = 12901

[pid 12900] waitpid(12901, Process 12900 suspended
 
[pid 12901] getppid()                   = 12900
[pid 12901] exit_group(0)               = ?
Process 12900 resumed
Process 12901 detached
<... waitpid resumed> NULL, 0)          = 12901
--- SIGCHLD (Child exited) @ 0 (0) ---
exit_group(0)                           = ?
Process 12900 detached
看出子进程里打出来的ppid等于父进程的id,为什么没有调用geipid()呢?这里编译器做了优化,因为clone()返回值就是子进程的pid。
2 再看线程的创建,用户程序创建线程要使用线程库:
查看本机使用的线程库:
~/code$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.6.1
~/code$ cat thread.c

#include
#include
#include

void *fun()
{
        getpid();
        getppid();
}

int main()
{
        pthread_t ntid;
        getppid();
        pthread_create(&ntid, NULL, fun, NULL);
        pthread_join(ntid, NULL);
        return 0;
}

~/code$ gcc -o thread_test -lpthread thread.c
~/code$ strace -f ./thread_test
execve("./thread_test", ["./thread_test"], [/* 38 vars */]) = 0
brk(0)                                  = 0x804a000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ee5000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=44092, ...}) = 0
mmap2(NULL, 44092, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7eda000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 H\0\000"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=112423, ...}) = 0
mmap2(NULL, 94688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7ec2000
mmap2(0xb7ed6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13) = 0xb7ed6000
mmap2(0xb7ed8000, 4576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7ed8000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260a\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=1339816, ...}) = 0
mmap2(NULL, 1349136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7d78000
mmap2(0xb7ebc000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x143) = 0xb7ebc000
mmap2(0xb7ebf000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7ebf000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d77000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7d77ac0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7ebc000, 4096, PROT_READ)   = 0
munmap(0xb7eda000, 44092)               = 0
set_tid_address(0xb7d77b08)             = 13015
set_robust_list(0xb7d77b10, 0xc)        = 0
rt_sigaction(SIGRTMIN, {0xb7ec6300, [], SA_SIGINFO}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0xb7ec6380, [], SA_RESTART|SA_SIGINFO}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
uname({sys="Linux", node="apollo", ...}) = 0
getppid()                               = 13014
mmap2(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7576000
brk(0)                                  = 0x804a000
brk(0x806b000)                          = 0x806b000
mprotect(0xb7576000, 4096, PROT_NONE)   = 0
clone(Process 13016 attached
child_stack=0xb7d764c4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb7d76bd8, {entry_number:6, base_addr:0xb7d76b90, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb7d76bd8) = 13016
[pid 13015] futex(0xb7d76bd8, FUTEX_WAIT, 13016, NULL
[pid 13016] set_robust_list(0xb7d76be0, 0xc) = 0
[pid 13016] getppid()                   = 13014
[pid 13016] _exit(0)                    = ?
Process 13016 detached
<... futex resumed> )                   = 0
exit_group(0)                           = ?
Process 13015 detached
看出线程的ppid等于创建它的进程的ppid,它们是同一线程组,而不是父子关系。而且NPTL使用了一种futex的锁。
阅读(274) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~