进程间通信--信号量+共享内存
来源:互联网 发布:情义我心知粤语版 编辑:程序博客网 时间:2024/05/17 08:40
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct semid_ds {
struct ipc_perm sem_perm; /* 对信号操作的许可权 */
__kernel_time_t sem_otime; /*对信号操作的最后时间 */
__kernel_time_t sem_ctime; /*对信号进行修改的最后时间 */
struct sem *sem_base; /*指向第一个信号 */
struct sem_queue *sem_pending; /* 等待处理的挂起操作 */
struct sem_queue **sem_pending_last; /* 最后一个正在挂起的操作 */
struct sem_undo *undo; /* 撤销的请求 */
unsigned short sem_nsems; /* 数组中的信号数 */
};
表 1 sem_op的取值和意义 取值范围操作意义 sem_op > 0 信号加上sem_op.表示进程释放控制的资源 sem_op = 0 如果没有设置IPC_NOWAIT,则进程进入睡眠,直到信号值为0;否则进程不会睡眠,直接返回EAGAIN sem_op < 0信号加上sem_op的值,若没有设置IPC_NOWAIT,则进程进入睡眠,直到资源可用。否则直接返回EAGAIN
/* arg for semctl system calls. */
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
unsigned short *array; /* array for GETALL & SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
void *__pad;
};
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct shmid_ds {
struct ipc_perm shm_perm; /* 操作许可 */
int shm_segsz; /* 共享内存大小,字节为单位 */
__kernel_time_t shm_atime; /* 最后一个进程访问共享内存的时间 */
__kernel_time_t shm_dtime; /* 最后一个进程离开共享内存的时间 */
__kernel_time_t shm_ctime; /* 最后一次修改共享内存的时间 */
__kernel_ipc_pid_t shm_cpid; /* 创建共享内存的进程ID */
__kernel_ipc_pid_t shm_lpid; /* 最后操作共享内存的进程ID */
unsigned short shm_nattch; /* 当前使用该贡献内存的进程数量 */
unsigned short shm_unused; /* compatibility */
void *shm_unused2; /* ditto - used by DIPC */
void *shm_unused3; /* unused */
};
参数shmaddr为shmat的返回值,该函数调用成功后,返回0,否则返回-1。
#include "shm_mem.h"
int main(int argc, char** argv)
{
int semid, shmid;
char *shmaddr;
char write_str[SHM_SIZE];
char *ret;
if((shmid = creatshm(".", 57, SHM_SIZE)) == -1) //创建或者获取共享内存
return -1;
/*建立进程和共享内存连接*/
if((shmaddr = shmat(shmid, (char*)0, 0)) == (char *)-1){
perror("attch shared memory error!\n");
exit(1);
}
if((semid = creatsem("./", 39, 1, 1)) == -1)//创建信号量
return -1;
while(1){
wait_sem(semid, 0);//等待信号量可以被获取
sem_p(semid, 0); //获取信号量
/***************写共享内存***************************************************/
printf("write : ");
ret = fgets(write_str, 1024, stdin);
if(write_str[0] == '#') // '#'结束读写进程
break;
int len = strlen(write_str);
write_str[len] = '\0';
strcpy(shmaddr, write_str);
/****************************************************************************/
sem_v(semid, 0); //释放信号量
usleep(1000); //本进程睡眠.
}
sem_delete(semid); //把semid指定的信号集从系统中删除
deleteshm(shmid); //从系统中删除shmid标识的共享内存
return 0;
}
#include "shm_mem.h"
int main(int argc, char** argv)
{
int semid, shmid;
char *shmaddr;
printf("What!!!!!!!!!!!\n");
if((shmid = creatshm(".", 57, SHM_SIZE)) == -1)
return -1;
if((shmaddr = shmat(shmid, (char*)0, 0)) == (char *)-1){
perror("attch shared memory error!\n");
exit(1);
}
if((semid = opensem("./", 39)) == -1)
return -1;
printf("read start....................\n");
while(1){
printf("read : ");
wait_sem(semid, 0); //等待信号量可以获取
if(sem_p(semid, 0) == -1) 获取信号量失败退出。当写者写入'#'时表示退出
break;
printf("%s", shmaddr);
sem_v(semid, 0);
usleep(1000);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <error.h>
#define SHM_SIZE 1024
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *buf_info;
void *pad;
};
/* 创建信号量函数*/
int creatsem(const char *pathname, int proj_id, int members, int init_val)
{
key_t msgkey;
int index, sid;
union semun semopts;
if((msgkey = ftok(pathname, proj_id)) == -1){
perror("ftok error!\n");
return -1;
}
if((sid = semget(msgkey, members, IPC_CREAT|0666)) == -1){
perror("semget call failed.\n");
return -1;
}
semopts.val = init_val;
for(index = 0; index < members; index++){
semctl(sid, index, SETVAL, semopts);
}
return sid;
}
int opensem(const char *pathname, int proj_id)
{
key_t msgkey;
int sid;
if((msgkey = ftok(pathname, proj_id)) == -1){
perror("ftok error!\n");
return -1;
}
if((sid = semget(msgkey, 0, 0666)) == -1){
perror("open semget call failed.\n");
return -1;
}
return sid;
}
/* p操作, 获取信号量*/
int sem_p(int semid, int index)
{
//struct sembuf sbuf = {0, -1, SEM_UNDO};
struct sembuf sbuf = {0, -1, IPC_NOWAIT};
if(index < 0){
perror("index of array cannot equals a minus value!\n");
return -1;
}
sbuf.sem_num = index;
if(semop(semid, &sbuf, 1) == -1){
perror("A wrong operation to semaphore occurred!\n");
return -1;
}
return 0;
}
/* V操作, 释放信号量*/
int sem_v(int semid, int index)
{
//struct sembuf sbuf = {0, 1, SEM_UNDO};
struct sembuf sbuf = {0, 1, IPC_NOWAIT};
if(index < 0){
perror("index of array cannot equals a minus value!\n");
return -1;
}
sbuf.sem_num = index;
if(semop(semid, &sbuf, 1) == -1){
perror("A wrong operation to semaphore occurred!\n");
return -1;
}
return 0;
}
/* 删除信号量几*/
int sem_delete(int semid)
{
return (semctl(semid, 0, IPC_RMID));
}
/* 等待信号量为1*/
int wait_sem(int semid, int index)
{
while(semctl(semid, index, GETVAL, 0) == 0)
{
//wait_num++;
usleep(500);
}
//printf("wait_num = %x\n", wait_num);
return 1;
}
/* 创建共享内存*/
int creatshm(char *pathname, int proj_id, size_t size)
{
key_t shmkey;
int sid;
if((shmkey = ftok(pathname, proj_id)) == -1){
perror("ftok error!\n");
return -1;
}
if((sid = shmget(shmkey, size, IPC_CREAT|0666)) == -1){
perror("shm call failed!\n");
return -1;
}
return sid;
}
/* 删除共享内存*/
int deleteshm(int sid)
{
void *p = NULL;
return (shmctl(sid, IPC_RMID, p));
}
上一篇:字符设备的信号量,阻塞和非阻塞,poll实现
下一篇:ps -aux 详解
- Live UC论视频会议对企业的重...
- 安装Oracle时在Linux上设置内...
- oc总结
- Linux内存分析(4) -- paging_i...
- 光明乳业—健康的首选...
- linux 常见服务端口
- 【ROOTFS搭建】busybox的httpd...
- xmanager 2.0 for linux配置
- 什么是shell
- linux socket的bug??
- 初学UNIX环境高级编程的,关于...
- chinaunix博客什么时候可以设...
- 一个访问量较大网站的服务器。...
- 收音机驱动与v4l2架构的关系,...
- 如何将linux驱动改为裸机驱动(...
lanlovehua2010-11-18 10:23:12
在shm_mem.h里的int creatsem(const char *pathname, int proj_id, int members, int init_val)函数里修改如下: //union semun semopts;union semun semopts_x;试一试。
lanlovehua2010-11-18 10:05:35
这个是头文件的问题,请看下面的文章:http://topic.csdn.net/t/20060714/15/4880830.html
chinaunix网友2010-11-16 11:04:07
谢谢你的代码 ,但我运行的时候有个错,error: storage size of ‘semopts’ isn’t known??
- 进程间通信--信号量+共享内存
- 进程间通信--信号量+共享内存
- Linux--进程间通信-共享内存-信号量
- 进程间通信—共享内存、信号量
- 进程通信--信号量,共享内存
- 通过共享内存和信号量实现进程间的通信
- Linux进程间通信之共享内存+信号量
- Linux--进程间通信(信号量,共享内存)(转)
- Linux--进程间通信(信号量,共享内存)
- 使用信号量和共享内存实现进程间通信
- Linux--进程间通信(信号量,共享内存)(转)
- Linux--进程间通信(信号量,共享内存)
- 进程间通信 "共享内存" 与 “信号量”的使用
- Linux进程间通信 共享内存+信号量+简单例子
- Linux进程间通信 共享内存+信号量+简单例子
- 进程间通信:管道,信号量,共享内存,消息队列
- Linux进程间通信--共享内存与信号量
- 进程间通信 内存共享信号量实例理解
- shell十三问之exec 跟 source 差在哪? 解析
- linux2.6.28-tty设备驱动学习(一)
- linux2.6.28-tty设备驱动学习(二)
- Linux2.6 DM9000驱动模编译为模块
- 字符设备的信号量,阻塞和非阻塞,poll实现
- 进程间通信--信号量+共享内存
- ps -aux 详解
- 从PC总线到ARM的内部总线
- 控制函数assert.h, setjmp.h和signal.h
- ADS分散加载文件及其应用
- 收藏:让你吃惊的60个绝对得看的常识!!!!
- linux内核可变参数分析
- Linux ELF文件学习(1)
- 一个程序,让你清楚区分二进制文件和文本文件