【轉貼】汐っ阳的嵌入式博客 /* * 共享内存 * 信号量控制共享内存的同步,实现父子进程通信, * 思路: 第一步,创建信号量,映像共享内存 第二步,创建子进程,让子进程继承父进程所有上下文 第三步,父进程睡眠一秒,让子进程获得CPU时间 第四步,子进程运行,立刻进行P操作 第五步,子进程睡眠4秒,主动放弃CPU 第六步,父进程获得CPU,但信号量已为0,无法进行P操作,只能继续打酱油,父进程被阻塞 第七步,子进程接着运行,最后释放共享内存,进行V操作, 第八步,父进程被换醒,获得信号锁,运行,最后,删除共享内存,退出程序 * Lzy 2011-6-16 */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <sys/sem.h> #define SHM_SIZE 1024 //共享内存的大小 int main(void) { int ret, //临时变量 pid, //进程id sme_id, //保存信号量描述符 shm_id; //保存共享内存描述符 key_t sme_key, //保存信号量键值 shm_key; //保存共享内存键值 char *shmp; //指向共享内存的首地址 struct shmid_ds dsbuf; //定义共享内存信息结构变量 struct sembuf lock = {0, -1, SEM_UNDO}; //信号量上锁操作的数组指针 struct sembuf unlock = {0, 1, SEM_UNDO | IPC_NOWAIT};//信号量解锁操作的数组指针 sme_key = ftok("/dev/shm/t2", 2); //获取信号量键值 if(sme_key < 0) { perror("ftok"); exit(0); } sme_id = semget(sme_key, 1, IPC_CREAT | 0666); //获取信号量ID if(sme_id < 0) { perror("semget"); exit(0); } shm_key = ftok("/dev/shm/t2", 1); //获取共享内存键值,路徑要事先建好 if(shm_key < 0) { perror("ftok"); exit(0); } shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666); //获取共享内存ID if(shm_id < 0) { perror("shmget"); exit(0); } shmp = shmat(shm_id, NULL, 0); //映像共享内存 if((int)shmp == -1) { perror("shmat"); exit(0); } pid = fork(); //创建子进程 if(pid < 0) { perror("fork"); exit(0); } else if(pid == 0) //子进程 { ret = semctl(sme_id, 0, SETVAL, 1); //初始化信号量,初值设为1 (不懂其意 if(ret == -1) { perror("semctl"); exit(0); } ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源 if(ret == -1) { perror("semop lock--c"); exit(0); } sleep(4); //让子进程睡眠4秒 strcpy(shmp, "hello\n"); //往共享内存写入数据 if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间 { perror("shmdt"); } ret = semop(sme_id, &unlock, 1); //解锁临界资源 if(ret == -1) { perror("semop unlock--c2"); exit(0); } } else //父进程 sleep(1); //先让子进程运行 ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源 if(ret == -1) { perror("semop lock"); exit(0); } if(shmctl(shm_id, IPC_STAT, &dsbuf) < 0) //获取共享内存信息 { perror("shmctl"); exit(0); } else /* 共享内存的状态信息获取成功 */ { printf("Shared Memory Information:\n"); printf("\tCreator PID: %d\n", dsbuf.shm_cpid); /* 输出创建共享内存进程的标识符 */ printf("\tSize(bytes): %d\n",dsbuf.shm_segsz); /* 输出共享内存的大小 */ printf("\tLast Operator PID: %d\n",dsbuf.shm_lpid); /* 输出上一次操作共享内存进程的标识符 */ printf("Received message : %s\n", (char *)shmp); /* 从共享内存中读取数据 */ } if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间 { perror("shmdt"); exit(0); } ret = semop(sme_id, &unlock, 1); //解锁临界资源 if(ret == -1) { perror("semop unlock--p"); exit(0); } if(shmctl(shm_id, IPC_RMID, NULL) < 0) /* 删除前面创建的共享内存 */ { perror("shmctl"); exit(0); } ret = semctl(sme_id, 0, IPC_RMID, NULL); //删除信号量 if(ret == -1) { perror("semctl"); exit(0); } } return 0; } ref : 汐っ阳的嵌入式博客
2012年1月18日 星期三
Share memory / Semaphore 之一
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言