相信自己,只有不想做的,没有做不到的。
分类: LINUX
2013-12-16 22:32:19
#include
#include
#include
#include
#include
#include
#include
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
(Linux-specific) */
};
int init_sem_value(int sem_id,int num,int value)
{
union semun var;
var.val = value;
if(semctl(sem_id,num,SETVAL,var) < 0)
{
perror("Fail to semctl");
exit(EXIT_FAILURE);
}
return 0;
}
//P操作
void P(int sem_id,int num)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = -1;
//SEM_UNDO :值的是进程异常退出的时候,释放它申请的资源
//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回
//0 :阻塞方式
buf.sem_flg = 0;
if(semop(sem_id,&buf,1) < 0)
{
perror("Fail to semop");
exit(EXIT_FAILURE);
}
return ;
}
//V操作
void V(int sem_id,int num)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = 1;
//SEM_UNDO :值的是进程异常退出的时候,释放它申请的资源
//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回
//0 :阻塞方式
buf.sem_flg = 0;
if(semop(sem_id,&buf,1) < 0)
{
perror("Fail to semop");
exit(EXIT_FAILURE);
}
return ;
}
//./a.out .
int main(int argc, const char *argv[])
{
char *addr;
int shm_id;
key_t key;
//先运行
if((key = ftok(argv[1],'k')) < 0)
{
perror("Fail to key");
exit(EXIT_FAILURE);
}
printf("key = %#x.\n",key);
/*
*int shmget(key_t key, size_t size, int shmflg);
*第一个参数:
*1.IPC_PRIVATE,每次都会获得一个新的共享内存,主要用于有亲缘关系的进程
*2.通过ftok函数获得
* key_t key;
* key = ftok(pathname,字符);
*
*第二个参数:
*共享内存大小
*
*第三个参数:
*IPC_CREAT,IPC_EXCL,权限
*/
//如果对应的key的共享内存不存在,创建,然后返回其ID
//如果对应的key的共享内存存在,直接返回ID
if((shm_id = shmget(key,1024,IPC_CREAT | 0666)) < 0)
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
printf("shm_id = %d.\n",shm_id);
//映射共享内存
if( ( addr = (char *)shmat(shm_id,NULL,0) ) == (char *)-1 )
{
perror("Fail to shmat");
exit(EXIT_FAILURE);
}
//**************************信号灯集*******************
int sem_id;
//创建信号灯集
if((sem_id = semget(key,2,IPC_CREAT | IPC_EXCL | 0666) ) < 0)
{
if((sem_id = semget(key,2,IPC_CREAT | 0666)) < 0)
{
perror("Fail to semget");
exit(EXIT_FAILURE);
}
}else{
//初始化信号灯集信号灯的值
init_sem_value(sem_id,0,0);
init_sem_value(sem_id,1,1);
}
while(1)
{
P(sem_id,0);
printf("%s.\n",addr);
V(sem_id,1);
if(strncmp(addr,"quit",4) == 0)
break;
}
//解除映射
if(shmdt(addr) < 0)
{
perror("Fail to shmdt");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);;
}
write.c代码如下:
#include
#include
#include
#include
#include
#include
#include
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
(Linux-specific) */
};
int init_sem_value(int sem_id,int num,int value)
{
union semun var;
var.val = value;
if(semctl(sem_id,num,SETVAL,var) < 0)
{
perror("Fail to semctl");
exit(EXIT_FAILURE);
}
return 0;
}
//P操作
void P(int sem_id,int num)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = -1;
//SEM_UNDO :值的是进程异常退出的时候,释放它申请的资源
//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回
//0 :阻塞方式
buf.sem_flg = 0;
if(semop(sem_id,&buf,1) < 0)
{
perror("Fail to semop");
exit(EXIT_FAILURE);
}
return ;
}
//V操作
void V(int sem_id,int num)
{
struct sembuf buf;
buf.sem_num = num;
buf.sem_op = 1;
//SEM_UNDO :值的是进程异常退出的时候,释放它申请的资源
//IPC_NOWAIT:没有申请到资源的时候,不阻塞,立即返回
//0 :阻塞方式
buf.sem_flg = 0;
if(semop(sem_id,&buf,1) < 0)
{
perror("Fail to semop");
exit(EXIT_FAILURE);
}
return ;
}
//./a.out .
int main(int argc, const char *argv[])
{
char *addr;
int shm_id;
key_t key;
//先运行
if((key = ftok(argv[1],'k')) < 0)
{
perror("Fail to key");
exit(EXIT_FAILURE);
}
printf("key = %#x.\n",key);
/*
*int shmget(key_t key, size_t size, int shmflg);
*第一个参数:
*1.IPC_PRIVATE,每次都会获得一个新的共享内存,主要用于有亲缘关系的进程
*2.通过ftok函数获得
* key_t key;
* key = ftok(pathname,字符);
*
*第二个参数:
*共享内存大小
*
*第三个参数:
*IPC_CREAT,IPC_EXCL,权限
*/
//如果对应的key的共享内存不存在,创建,然后返回其ID
//如果对应的key的共享内存存在,直接返回ID
if((shm_id = shmget(key,1024,IPC_CREAT | 0666)) < 0)
{
perror("Fail to shmget");
exit(EXIT_FAILURE);
}
printf("shm_id = %d.\n",shm_id);
//映射共享内存
if( ( addr = (char *)shmat(shm_id,NULL,0) ) == (char *)-1 )
{
perror("Fail to shmat");
exit(EXIT_FAILURE);
}
//**************************信号灯集*******************
int sem_id;
//创建信号灯集
if((sem_id = semget(key,2,IPC_CREAT | IPC_EXCL | 0666) ) < 0)
{
if((sem_id = semget(key,2,IPC_CREAT | 0666)) < 0)
{
perror("Fail to semget");
exit(EXIT_FAILURE);
}
}else{
//初始化信号灯集信号灯的值
init_sem_value(sem_id,0,0);
init_sem_value(sem_id,1,1);
}
while(1)
{
P(sem_id,1);
fgets(addr,1024,stdin);
V(sem_id,0);
if(strncmp(addr,"quit",4) == 0)
break;
}
//解除映射
if(shmdt(addr) < 0)
{
perror("Fail to shmdt");
exit(EXIT_FAILURE);
}
//删除共享内存对象
//真正删除:在共享内存映射次数为0的时候,才会删除
if(shmctl(shm_id,IPC_RMID,NULL) < 0)
{
perror("Fail to shmctl");
exit(EXIT_FAILURE);
}
usleep(500);
//删除信号灯集合
if(semctl(sem_id,0,IPC_RMID) < 0)
{
perror("Fail to semctl");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);;
}