面试题答案
一键面试解决方法
在C语言环境下,解决共享内存同步问题可以使用信号量(Semaphore)。信号量是一个整型变量,通过对其值的原子操作来实现同步。具体步骤如下:
- 创建信号量:使用
semget
函数创建一个信号量集。 - 初始化信号量:使用
semctl
函数对信号量进行初始化,设置其初始值。 - 获取信号量:使用
semop
函数获取信号量,如果信号量值为0,则进程会阻塞等待。 - 释放信号量:使用
semop
函数释放信号量,将信号量值加1,唤醒等待的进程。
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <unistd.h>
#define SHM_SIZE 1024
// 定义信号量操作结构
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int main() {
key_t key;
int shmid, semid;
char *shmaddr;
// 创建共享内存键值
if ((key = ftok(".", 'a')) == -1) {
perror("ftok");
exit(1);
}
// 创建共享内存
if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) == -1) {
perror("shmget");
exit(1);
}
// 挂载共享内存
if ((shmaddr = (char *)shmat(shmid, NULL, 0)) == (void *)-1) {
perror("shmat");
exit(1);
}
// 创建信号量键值
if ((key = ftok(".", 'b')) == -1) {
perror("ftok");
exit(1);
}
// 创建信号量集
if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) {
perror("semget");
exit(1);
}
// 初始化信号量
union semun semarg;
semarg.val = 1;
if (semctl(semid, 0, SETVAL, semarg) == -1) {
perror("semctl");
exit(1);
}
struct sembuf semopbuf;
semopbuf.sem_num = 0;
semopbuf.sem_op = -1;
semopbuf.sem_flg = 0;
// 获取信号量
if (semop(semid, &semopbuf, 1) == -1) {
perror("semop");
exit(1);
}
// 使用共享内存
sprintf(shmaddr, "Hello, shared memory!");
printf("Process %d wrote: %s\n", getpid(), shmaddr);
semopbuf.sem_op = 1;
// 释放信号量
if (semop(semid, &semopbuf, 1) == -1) {
perror("semop");
exit(1);
}
// 分离共享内存
if (shmdt(shmaddr) == -1) {
perror("shmdt");
exit(1);
}
// 删除共享内存
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(1);
}
// 删除信号量
if (semctl(semid, 0, IPC_RMID) == -1) {
perror("semctl");
exit(1);
}
return 0;
}
上述代码展示了在C语言中如何使用信号量解决共享内存的同步问题。代码创建了共享内存和信号量,通过获取和释放信号量来确保对共享内存的安全访问。