您的位置:首页 > 运维架构 > Linux

linux C学习笔记05--信号量与共享内存(进程同步)

2015-05-29 14:31 453 查看
花了半天时间把信号量与共享内存整合到了一起,先来看信号量代码,semaphore.c 当中sem_P()和sem_V()函数分别为信号量等待和信号量释放。

两个进程同时访问共享内存,为了避免发生同时读写产生不必要的错误,加入了信号量进行同步。对使用共享内存的区域加上互斥锁,同时只有一个进程能访问共享内存,时其他进程必须等待信号量资源释放后才能继续访问

/*************************************************************************
> File Name: semaphore.c
> Author: hailin.ma
> Mail: mhl2018@126.com
> Created Time: Thu 28 May 2015 09:29:35 AM CST
************************************************************************/

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>

#define SEM_KEY 27

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 create_semaphore()
{
int semid;
union semun sembuf;

sembuf.val = 1;

if((semid = semget(SEM_KEY,1, IPC_CREAT|IPC_EXCL|0666)) == -1)
{
if(errno == EEXIST)
{
semid = semget(SEM_KEY,0,0);
if(semid == -1)
{
perror("semget");
return -1;
}
else
{
if (semctl(semid,0,SETVAL,sembuf) == -1)
{
perror("semctl");
return -1;
}
else
{
return semid;
}
}

}
else
{
perror("semget");
return -1;
}
}
else
{
if (semctl(semid,0,SETVAL,sembuf) == -1)
{
perror("semctl");
return -1;
}
}

return semid;
}

int delete_semaphore(int semid)
{
union semun sembuf;
if(semctl(semid,0,IPC_RMID,sembuf) == -1)
{
perror("delete_semaphore");
return -1;
}
}

int sem_P(int semid)
{
struct sembuf sbuf;
sbuf.sem_num = 0;
sbuf.sem_op = -1;
sbuf.sem_flg = SEM_UNDO;

if(semop(semid,&sbuf,1) == -1)
{
perror("sem_P");
return -1;
}

return 0;
}

int sem_V(int semid)
{
struct sembuf sbuf;
sbuf.sem_num = 0;
sbuf.sem_op = 1;
sbuf.sem_flg = SEM_UNDO;

if(semop(semid,&sbuf,1) == -1)
{
perror("sem_P");
return -1;
}
}


下面是共享内存代码:

/*************************************************************************
> File Name: share_memory.c
> Author: hailin.ma
> Mail: mhl2018@126.com
> Created Time: Wed 27 May 2015 11:19:26 PM CST
************************************************************************/

#include<stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>

#define SHARE_MEM_KEY 26
#define MEMORY_SIZE 1000

int create_shm(char **shmptr)
{
int shmid;

//if((shmid = shmget(IPC_PRIVATE,200,IPC_CREAT|IPC_EXCL|0666)) == -1)
if((shmid = shmget(SHARE_MEM_KEY,MEMORY_SIZE,IPC_CREAT|IPC_EXCL|0666)) == -1)
{
if(errno == EEXIST)
{
shmid = shmget(SHARE_MEM_KEY,0,0);
if(shmid == -1)
{
perror("shmget");
return -1;
}
else
{
if((*shmptr = shmat(shmid,0,0666)) == (void*)-1)
{
perror("shmat");
return -1;
}
else
{
return shmid;
}
}
}
else
{
perror("shmget");
return -1;
}
}

if((*shmptr = shmat(shmid,0,0)) == (void*)-1)
{
perror("shmat");
return -1;
}

return shmid;
}

int delete_shm(int shmid,char *shmptr)
{
shmdt(shmptr);
if(shmctl(shmid,IPC_RMID,NULL) == -1)
{
perror("delete_shm");
return -1;
}

return 0;
}


main函数代码:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

extern int create_shm(char **shmptr);
extern int create_semaphore();
extern int delete_semaphore();
extern int sem_P(int semid);
extern int sem_V(int semid);
extern int delete_shm(int shmid,char *shmptr);

int main(int argc,char* argv[])
{
int shmid;
char *shmptr;
int semid;

if((shmid =create_shm(&shmptr)) == -1)
{
printf("create_shm error \n");
return -1;
}
if(argc > 1)
{
semid = *(int*)shmptr;        //get semid from share memory

//this is client
while(1)
{
printf("input str to share memory:");
sem_P(semid);
gets(shmptr);
sem_V(semid);
if(shmptr[0] == 'q')        //quit
{
shmdt(shmptr);            //disconnect to the share memory but will not dellect the memery
break;
}
}
}
else
{
if((semid = create_semaphore()) == -1)
{
perror("main create_semaphore");
delete_shm(shmid,shmptr);
return -1;
}
*(int*)shmptr = semid;
printf("share memory is: %d \n",*(int*)shmptr);

//this is server
while(1)
{
sleep(2);
sem_P(semid);
printf("share memory is: %s \n",shmptr);
sem_V(semid);
if(shmptr[0] == 'q')
{
delete_shm(shmid,shmptr);
delete_semaphore(semid);
break;
}
}
}

printf("into sleeping\n");
sleep(3);
printf("out sleeping\n");

return 0;
}


运行效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: