代码
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <error.h>
#define SIZE 1024
int main()
{
int shmid ;
char *shmaddr ;
struct shmid_ds buf ;
int flag = 0 ;
int pid ;
//获取共享内存区域的id即shmid
shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT|0600 );//0600 = SHM_R|SHM_W
if ( shmid < 0 )
{
perror("get shm ipc_id error");
return -1 ;
}
pid = fork();
if ( pid == 0 )
{
//根据shmid把共享内存区域映射到调用进程的地址空间中去,这样,进程就可以方便地对共享区域进行访问操作。
shmaddr = (char *)shmat(shmid, NULL, 0) ;
if ( shmaddr == NULL )
{
perror("shmat addr error") ;
return -1 ;
}
//把字符串拷贝到共享内存内
printf("child process pid is %d\n",getpid());
strcpy(shmaddr, "Hi, I am child process jy!\n") ;
//用来解除进程对shmaddr所在的共享内存区域的映射
shmdt(shmaddr);
return 0;
}
else if ( pid > 0) {
sleep(10) ;
//实现对共享内存区域的控制操作
/* IPC_STAT use to get `ipc_perm' options. */
flag = shmctl(shmid, IPC_STAT, &buf) ;
if ( flag == -1 )
{
perror("shmctl shm error") ;
return -1 ;
}
printf("shm_segsz =%d bytes\n", buf.shm_segsz ) ;
printf("parent pid=%d, shm_cpid = %d \n", getpid(), buf.shm_cpid ) ;
printf("chlid pid=%d, shm_lpid = %d \n",pid , buf.shm_lpid ) ;
shmaddr = (char *)shmat(shmid, NULL, 0 ) ;
if ( shmaddr == NULL )
{
perror("shmat addr error") ;
return -1;
}
printf("%s", shmaddr) ;
shmdt(shmaddr) ;
// #define IPC_RMID 0 /* Remove identifier. */
shmctl(shmid, IPC_RMID, NULL) ;
}
else{
perror("fork error") ;
shmctl(shmid, IPC_RMID, NULL) ;
}
return 0 ;
}
调试
www:/mnt/hgfs/Linux/testCPro # gdb sem
GNU gdb (GDB) SUSE (7.3-0.6.1)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-suse-linux”.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/…
Reading symbols from /mnt/hgfs/Linux/testCPro/sem…done.
//设置detach-on-fork off后gdb就可以控制父进程和子进程
(gdb) set detach-on-fork off
//设置断点
(gdb) b main
(gdb) r
//单步跟踪到fork处
(gdb) n
22 pid = fork();
//执行fork后可以查看进程信息
(gdb) info inferiors
Num Description Executable
2 process 12084 /mnt/hgfs/Linux/testCPro/sem //子进程
* 1 process 12081 /mnt/hgfs/Linux/testCPro/sem //父进程
//可以通过命令inferior 2切换到子进程调试,当然也可以通过inferior 1进入父进程
(gdb) inferior 2
[Switching to inferior 2 [process 12084] (/mnt/hgfs/Linux/testCPro/sem)]
[Switching to thread 2 (process 12084)]
0 0x00007ffff7b0fcff in fork () from /lib64/libc.so.6
(gdb) p getpid()
$2 = 12084
//且换到父进程
(gdb) inferior 1
(gdb) p getpid()
$3 = 12081`