导航:首页 > 网络营销 > 共享内存sem

共享内存sem

发布时间:2020-12-28 12:09:41

1、LINUX 信号量共存 共享内存通信

|/***Msginput.c***/
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include"Mysem.h"

int main(){
FILE *fp;
int empty;
int full;
int mutex;
char * shm;
int shmid;
fp = fopen("shmid","r");
fread(&shmid,sizeof(int), 1, fp);
fread(&empty,sizeof(int), 1, fp);
fread(&full,sizeof(int), 1, fp);
fread(&mutex,sizeof(int), 1, fp);

fclose(fp);
shm = shmat(shmid, NULL, 0);

while(1){

P(&empty);
P(&mutex);

scanf("%s", shm);

if(strcmp(shm, "END") == 0){

V(&mutex);
V(&full);
break;
}

V(&mutex);
V(&full);

}
return 0;
}

/****Mysem.c*****/
#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/shm.h>

#include<sys/sem.h>

#include<unistd.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include "Mysem.h"

#define BUFFER_SIZE 512

int main(){

char *shm;

int empty;

int full;

int mutex;

int shmid;

int pid;

int i;

FILE *fp;

// int init_sem_value = 0;

empty = semget(IPC_PRIVATE, 1, (0600|_CREAT));

if(empty == -1){

perror("semget");

exit(1);

}

if(semctl(empty, 0, SETVAL, 1)<0){

perror("semctl");

exit(1);

}

full = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));

if(full == -1){

perror("semget");

exit(1);

}

if(semctl(full, 0, SETVAL, 0)<0){

perror("semctl");

exit(1);

}

mutex = semget(IPC_PRIVATE, 1, (0600|IPC_CREAT));

if(mutex == -1){

perror("semget");

exit(1);

}

if(semctl(mutex, 0, SETVAL, 1)<0){

perror("semctl");

exit(1);

}

shmid = shmget(IPC_PRIVATE, (BUFFER_SIZE*sizeof(char)),(IPC_CREAT|0600));

if(shmid == -1){

perror("shmget");

exit(1);

}

shm = shmat(shmid, NULL, 0);

if(shm == (char*)-1){

perror("shmat");

exit(1);

}

fp = fopen("shmid","w");

fwrite(&shmid, sizeof(int), 1, fp);

fwrite(&empty, sizeof(int), 1, fp);

fwrite(&full, sizeof(int), 1, fp);

fwrite(&mutex, sizeof(int), 1, fp);

fclose(fp);

pid = fork();

if(pid == 0){

execlp("./Msginput", "./Msginput",0);

perror("execlp");

exit(1);

}else{

while(1){

P(&full);

P(&mutex);

printf("%s\n", shm);

if(strcmp(shm,"END") == 0){

V(&mutex);

V(&empty);

break;

}

V(&mutex);

V(&empty);

}

}

wait(0);

if(semctl(full, 0, IPC_RMID, 1) == -1){

perror("semctl");

exit(1);

}

if(semctl(empty, 0, IPC_RMID, 1) == -1){

perror("semctl");

exit(1);

}

if(semctl(mutex, 0, IPC_RMID, 1) == -1){

perror("semctl");

exit(1);

}

if(shmctl(shmid, IPC_RMID, NULL) == -1){

perror("shmctl");

exit(1);

}

exit(0);

}

/****Mysem.h*****/
void P(int *s);
void V(int *s);

extern void *shmat (int __shmid, __const void *__shmaddr, int __shmflg);

void P(int *s){
struct sembuf sembuffer, *sops;
sops=&sembuffer;
sops->sem_num = 0;
sops->sem_op = -1;
sops->sem_flg = 0;
if(semop(*s, sops, 1)<0){
perror("semop");
exit(1);
}
return ;
}
void V(int *s){
struct sembuf sembuffer, *sops;
sops = &sembuffer;
sops->sem_num = 0;
sops->sem_op = 1;
sops->sem_flg = 0;
if(semop(*s, sops, 1)<0){
perror("semop");
exit(1);
}
return;
}

2、linux进程间通信问题 我想用共享内存的方式实现信号量控制一个不许并行的的函数 请问下面我的代码合理吗

我想你的目的是有一段代码 (即你标的 /*..........只能单独进行的函数.........*/)
在任意时刻最多只能有最多一个进程执行,是吧。

首先,你的做法是错的…… 简单的说,原因是由于
while( *shmaddr );
*shmaddr = 1;
这两行代码不是一个原子操作,从while判断出 *shmaddr等于0 到 *shmaddr=1 之间,另外一个或多个进程可能也会得到 *shmaddr==0 的判断,从而导致多个进程同时进入 /*..........只能单独进行的函数.........*/
具体关于互斥的基本原理,以及你为什么错,可以找一本讲操作系统原理 (关于进程同步的内容)去看。

所以,用 shared memory 来实现进程同步肯定是不行的,正确的做法是使用 semaphore, 具体可以参考 《unix 环境高级编程》中关于 semaphore (信号量)使用的章节。

与共享内存sem相关的知识