shm_open shmget
时间: 2023-10-02 22:13:32 浏览: 168
`shm_open()` 和 `shmget()` 都是用于共享内存的函数,但是它们是针对不同的操作系统。
`shm_open()` 是在类 UNIX 操作系统中使用的函数,用于打开一个具有一定名字的共享内存对象,并返回一个文件描述符。开发者可以使用这个文件描述符来访问共享内存对象。`shm_open()` 函数的原型如下:
```c
#include <sys/mman.h>
int shm_open(const char *name, int oflag, mode_t mode);
```
`shmget()` 是在 Linux 操作系统中使用的函数,用于创建一个具有一定 key 值的共享内存区域,并返回一个标识符(即 shmid)。开发者可以使用这个 shmid 来访问共享内存区域。`shmget()` 函数的原型如下:
```c
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
```
两个函数都是为了实现进程间通信而设计的,但是它们的使用方法和参数有所不同。在使用共享内存之前,开发者需要先明确自己的操作系统是哪个,然后再选择相应的函数来实现共享内存的功能。
相关问题
优化这段代码//为消息发送程序 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/stat.h> #include<fcntl.h> #include<pthread.h> #include<semaphore.h> #include<sys/types.h> #include<unistd.h> #include<sys/ipc.h> #include<sys/shm.h> static const char * MUTEX_NAME = "mutex_shm"; static const char * FULL_NAME = "full_shm"; #define INPUT_SIZE 1024 //输入的最大长度 #define KEY_NUM 8848 void P(sem_t *semPtr){ sem_wait(semPtr); } void V(sem_t *semPtr){ sem_post(semPtr); } int main(int argc, char** argv){ key_t key = KEY_NUM; //为共享内存段命名 char input[INPUT_SIZE]; char reply[INPUT_SIZE]; int shmid; char* shmptr; //创建共享内存 shmid = shmget(key, INPUT_SIZE, IPC_CREAT | 0666); if(shmid < 0) { perror("Receiver: Shmget Error"); exit(EXIT_FAILURE); } //启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间 shmptr = shmat(shmid, NULL, 0); sem_t* mutex = sem_open(MUTEX_NAME,O_CREAT); //共享内存只能同时一个程序访问 sem_t* full = sem_open(FULL_NAME,O_CREAT); //共享内存的消息数量 printf("请输入一串字符:"); scanf("%s",input); P(mutex); strcpy(shmptr,input); V(mutex); V(full); printf("消息已发送给receiver!\n"); //把共享内存从当前进程中分离 if(shmdt(shmptr) == -1){ fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } return 0; }
这段代码可以进行以下优化:
1. 在创建信号量时,应该设置初始值,否则可能会出现死锁的情况。
2. 在使用信号量时,应该先判断是否成功获取信号量,否则可能会出现程序崩溃的情况。
3. 应该检查共享内存的连接是否成功。
4. 在结束程序之前,应该关闭信号量和共享内存。
下面是优化后的代码:
```
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
static const char * MUTEX_NAME = "mutex_shm";
static const char * FULL_NAME = "full_shm";
#define INPUT_SIZE 1024 //输入的最大长度
#define KEY_NUM 8848
void P(sem_t *semPtr){
if(sem_wait(semPtr) != 0){
perror("P: sem_wait() failed");
exit(EXIT_FAILURE);
}
}
void V(sem_t *semPtr){
if(sem_post(semPtr) != 0){
perror("V: sem_post() failed");
exit(EXIT_FAILURE);
}
}
int main(int argc, char** argv){
key_t key = KEY_NUM; //为共享内存段命名
char input[INPUT_SIZE];
int shmid;
char* shmptr;
sem_t* mutex;
sem_t* full;
//创建共享内存
shmid = shmget(key, INPUT_SIZE, IPC_CREAT | 0666);
if(shmid < 0)
{
perror("Receiver: Shmget Error");
exit(EXIT_FAILURE);
}
//启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间
shmptr = shmat(shmid, NULL, 0);
if(shmptr == (char*)-1){
perror("shmat failed");
exit(EXIT_FAILURE);
}
//创建信号量
mutex = sem_open(MUTEX_NAME, O_CREAT, 0666, 1);
if(mutex == SEM_FAILED){
perror("sem_open(mutex) failed");
exit(EXIT_FAILURE);
}
full = sem_open(FULL_NAME, O_CREAT, 0666, 0);
if(full == SEM_FAILED){
perror("sem_open(full) failed");
exit(EXIT_FAILURE);
}
printf("请输入一串字符:");
scanf("%s",input);
//获取信号量
P(mutex);
strcpy(shmptr,input);
V(mutex);
V(full);
printf("消息已发送给receiver!\n");
//关闭信号量和共享内存
sem_close(mutex);
sem_close(full);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
```
sem_open sem_wait实现两个进程读写共享内存的同步,包括两个进程,两个信号量
可以通过以下步骤来实现两个进程读写共享内存的同步,包括两个进程,两个信号量:
1. 定义共享内存区域
```c
#include <sys/shm.h>
int shmid = shmget(key, size, flag);
void *shmaddr = shmat(shmid, addr, flag);
```
2. 定义两个信号量
```c
#include <semaphore.h>
sem_t *sem1 = sem_open("/sem1", O_CREAT, 0644, 1);
sem_t *sem2 = sem_open("/sem2", O_CREAT, 0644, 0);
```
3. 进程1写入共享内存
```c
sem_wait(sem1);
memcpy(shmaddr, data, size);
sem_post(sem2);
```
4. 进程2读取共享内存
```c
sem_wait(sem2);
memcpy(data, shmaddr, size);
sem_post(sem1);
```
5. 删除信号量和共享内存
```c
sem_close(sem1);
sem_close(sem2);
sem_unlink("/sem1");
sem_unlink("/sem2");
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, 0);
```
这样,通过使用两个信号量分别控制进程1和进程2对共享内存的读写,可以实现两个进程的同步。其中,`sem1` 的初始值为 1,`sem2` 的初始值为 0,保证进程1先写入共享内存,进程2再读取共享内存。同时,需要注意在使用完共享内存和信号量后,要将其删除,以避免资源泄漏。
阅读全文