请问UXIN系统中信号量是怎么绑定共享内存的
请教UXIN系统中信号量是如何绑定共享内存的?
我们都知道进程是通过获取信号量来访问共享内存的,但是操作系统又如何知道信号量是控制哪个共享内存的,这个是由程序来实现的还是由操作系统来控制的?如果是由程序来实现的,那又是怎么做的呢?
------解决方案--------------------
信号量 -> semaphore?它与 shm 是独立的,只是程序之间的一种约定。譬如
sem_t -> @/app1/sem1
shm -> /dev/shm/app1_shm1
两个程序约定,只有当获取了 @/app1/sem1 的时候才能操作 /dev/shm/app1_shm1
就这么回事。至于这两个东西是不是必须在物理上有所关联,答案是否定的。
----
到不如 mmap 一个文件,然后用 flock / futex 去缩这个文件 / 内存块的某个 byte 来的精简
------解决方案--------------------
在访问共享内存前,首先试图去获得一个信号量旗标。如果成功,本进/线程就获得了对共享内存的访问权,在释放信号量旗标前其他进/线程无法获得该旗标,接下来本过程就可以对内存进行读写等操作。在共享内存使用完毕后,本进/线程释放旗标,其他进/线程又可以成功获取该信号量旗标。下面是简单的例子(程序中的函数和结构等请自己查手册):
iSemID = semget(SEMKEY, 1, S_IRUSR | S_IWUSR); //获取信号量
if(iSemID != -1) {
tSops.sem_num = 0;
tSops.sem_op = -(PROCESS_MAX);
tSops.sem_flg = 0;
iRc = semop(iSemID, &tSops, 1);
if(iRc == -1) {
printf("semop(ON) failed."); //信号量操作失败
}
tSops.sem_op = 0 - tSops.sem_op;
} else {
printf("semget failed."); //获取信号量失败
}
iShmID = shmget(MEMKEY, sizeof(....), S_IRUSR | S_IWUSR); //获取共享内存
if(iShmID != -1){
pStruct = (... *)shmat(iShmID, NULL, 0);
if(pStruct == SHM_FAILED){
printf("shmat failed."); //映射共享内存失败
}
}else{
printf("shmget failed."); //获取共享内存失败
}
........ //程序逻辑
iRc = shmdt(pStruct); //取消共享内存映射
if(iRc == -1){
sprintf("shmdt failed."); //取消共享内存映射失败
}
iRc = semop(iSemID, &tSops, 1); //释放信号量
if(iRc == -1){
sprintf("semop(OFF) failed."); //释放信号量失败
}
实际上系统提供的任一互斥机制都可以和某种资源组合,将对这一资源的访问描述为互斥的,而不仅仅是上述的信号量和共享内存一种情况。
我们都知道进程是通过获取信号量来访问共享内存的,但是操作系统又如何知道信号量是控制哪个共享内存的,这个是由程序来实现的还是由操作系统来控制的?如果是由程序来实现的,那又是怎么做的呢?
------解决方案--------------------
信号量 -> semaphore?它与 shm 是独立的,只是程序之间的一种约定。譬如
sem_t -> @/app1/sem1
shm -> /dev/shm/app1_shm1
两个程序约定,只有当获取了 @/app1/sem1 的时候才能操作 /dev/shm/app1_shm1
就这么回事。至于这两个东西是不是必须在物理上有所关联,答案是否定的。
----
到不如 mmap 一个文件,然后用 flock / futex 去缩这个文件 / 内存块的某个 byte 来的精简
------解决方案--------------------
在访问共享内存前,首先试图去获得一个信号量旗标。如果成功,本进/线程就获得了对共享内存的访问权,在释放信号量旗标前其他进/线程无法获得该旗标,接下来本过程就可以对内存进行读写等操作。在共享内存使用完毕后,本进/线程释放旗标,其他进/线程又可以成功获取该信号量旗标。下面是简单的例子(程序中的函数和结构等请自己查手册):
iSemID = semget(SEMKEY, 1, S_IRUSR | S_IWUSR); //获取信号量
if(iSemID != -1) {
tSops.sem_num = 0;
tSops.sem_op = -(PROCESS_MAX);
tSops.sem_flg = 0;
iRc = semop(iSemID, &tSops, 1);
if(iRc == -1) {
printf("semop(ON) failed."); //信号量操作失败
}
tSops.sem_op = 0 - tSops.sem_op;
} else {
printf("semget failed."); //获取信号量失败
}
iShmID = shmget(MEMKEY, sizeof(....), S_IRUSR | S_IWUSR); //获取共享内存
if(iShmID != -1){
pStruct = (... *)shmat(iShmID, NULL, 0);
if(pStruct == SHM_FAILED){
printf("shmat failed."); //映射共享内存失败
}
}else{
printf("shmget failed."); //获取共享内存失败
}
........ //程序逻辑
iRc = shmdt(pStruct); //取消共享内存映射
if(iRc == -1){
sprintf("shmdt failed."); //取消共享内存映射失败
}
iRc = semop(iSemID, &tSops, 1); //释放信号量
if(iRc == -1){
sprintf("semop(OFF) failed."); //释放信号量失败
}
实际上系统提供的任一互斥机制都可以和某种资源组合,将对这一资源的访问描述为互斥的,而不仅仅是上述的信号量和共享内存一种情况。