如何使用共享内存与信号量,信号量和信号的区别

博主最新文章
博主热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)博客访问: 144683
博文数量: 37
博客积分: 791
博客等级: 军士长
技术积分: 510
注册时间:
分类: 嵌入式 21:47:31
信号量函数定义如下:
int semctl(int sem_id, int sem_num, int command, ...);
int semget(key_t key, int num_sems, int sem_flags);
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);semop
函数semop用来改变信号量的值:
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);
第一个参数,sem_id,是由semget函数所返回的信号量标识符。第二个参数,sem_ops,是一个指向结构数组的指针,其中的每一个结构至少包含下列成员:
struct sembuf {
&&& short sem_
&&& short sem_
&&& short sem_
第一个成员,sem_num,是信号量数目,通常为0,除非我们正在使用一个信号量数组。sem_op成员是信号量的变化量值。(我们可以以任何量改变信
号量值,而不只是1)通常情况下中使用两个值,-1是我们的P操作,用来等待一个信号量变得可用,而+1是我们的V操作,用来通知一个信号量可用。
最后一个成员,sem_flg,通常设置为SEM_UNDO。这会使得操作系统跟踪当前进程对信号量所做的改变,而且如果进程终止而没有释放这个信号量,
如果信号量为这个进程所占有,这个标记可以使得操作系统自动释放这个信号量。将sem_flg设置为SEM_UNDO是一个好习惯,除非我们需要不同的行
为。如果我们确实变我们需要一个不同的值而不是SEM_UNDO,一致性是十分重要的,否则我们就会变得十分迷惑,当我们的进程退出时,内核是否会尝试清
理我们的信号量。
semop的所用动作会同时作用,从而避免多个信号量的使用所引起的竞争条件。我们可以在手册页中了解关于semop处理更为详细的信息。
semctl函数允许信号量信息的直接控制:
int semctl(int sem_id, int sem_num, int command, ...);
第一个参数,sem_id,是由semget所获得的信号量标识符。sem_num参数是信号量数目。当我们使用信号量数组时会用到这个参数。通常,如果
这是第一个且是唯一的一个信号量,这个值为0。command参数是要执行的动作,而如果提供了额外的参数,则是unionsemun,根据X/OPEN
规范,这个参数至少包括下列参数:
union semun {
&&& struct semid_ds *
&&& unsigned short *
许多版本的Linux在头文件(通常为sem.h)中定义了semun联合,尽管X/Open确认说我们必须定义我们自己的联合。如果我们发现我们确实需
要定义我们自己的联合,我们可以查看semctl手册页了解定义。如果有这样的情况,建议使用手册页中提供的定义,尽管这个定义与上面的有区别。
有多个不同的command值可以用于semctl。在这里我们描述两个会经常用到的值。要了解semctl功能的详细信息,我们应该查看手册页。
这两个通常的command值为:
SETVAL:用于初始化信号量为一个已知的值。所需要的值作为联合semun的val成员来传递。在信号量第一次使用之前需要设置信号量。
IPC_RMID:当信号量不再需要时用于删除一个信号量标识。
semctl函数依据command参数会返回不同的值。对于SETVAL与IPC_RMID,如果成功则会返回0,否则会返回-1。
信号量与共享内存的共同使用例子:write 端:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include "sem.h"
&&typedef struct
&&&&char buf[1024];
&&int main(int argc, const char *argv[])
&&&&key_t key;
&&&&memory *p = NULL;
&&&&int shmid;
&&&&int create_flag = 0;
&&&&int sem_id;
&&&&&&if ((key = ftok(".", 'a')) < 0)
&&&&&&&&perror("failed to get key");
&&&&&&&&exit(-1);
&&&&&&if ((sem_id = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL)) < 0)
&&&&&&&&if (errno == EEXIST)
&&&&&&&&&&&&if ((sem_id = semget(key, 1, 0666)) < 0)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&perror("failed to semget");
&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&}
&&&&&&init_sem(sem_id, 0);
&&&&&&if ((shmid = shmget(key, sizeof(memory), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
&&&&&&&&if (errno == EEXIST)
&&&&&&&&&&&&if ((shmid = shmget(key, sizeof(memory), 0666)) < 0)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&perror("failed to shmget memory");
&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&}
&&&&&&&&else
&&&&&&&&&&&&perror("failed to shmget");
&&&&&&&&&&&&exit(-1);
&&&&&&&&create_flag = 1;
&&&&&&if ((p = shmat(shmid, NULL, 0)) == (void *)(-1))
&&&&&&&&perror("failed to shmat memory");
&&&&&&&&exit(-1);
&&&&&&while(1)
&&&&&&&&printf(">");
&&&&&&&&fgets(p->buf, sizeof(p->buf), stdin);
&&&&&&&&p->buf[strlen(p->buf) - 1] = 0;
&&&&&&&&&&sem_v(sem_id);
&&&&&&&&&&if (strncmp(p->buf, "quit", 4) == 0)
&&&&&&&&&&&&break;
&&&&&&if (create_flag == 1)
&&&&&&&&if (shmdt(p) < 0)
&&&&&&&&&&&&perror("failed to shmdt memory");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&if (shmctl(shmid, IPC_RMID, NULL) == -1)
&&&&&&&&&&&&perror("failed to delete share memory");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&delete_sem(sem_id);
&&&&&&return 0;
}read 端:#include <stdio.h>
&&&&#include <stdlib.h>
&&&&#include <string.h>
&&&&#include <sys/types.h>
&&&&#include <sys/ipc.h>
&&&&#include <sys/shm.h>
&&&&#include <errno.h>
&&&&#include "sem.h"
&&&&&&&&&&typedef struct
&&&&&&&&char buf[1024];
&&&&}memory;
&&&&&&&&&&int main(int argc, const char *argv[])
&&&&&&&&key_t key;
&&&&&&&&int shmid;
&&&&&&&&memory *p = NULL;
&&&&&&&&int create_flag = 0;
&&&&&&&&int sem_id;
&&&&&&&&&&&&&&if ((key = ftok(".", 'a')) < 0)
&&&&&&&&&&&&perror("failed to get key");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&if ((sem_id = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL)) < 0)
&&&&&&&&&&&&if (errno == EEXIST)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if ((sem_id = semget(key, 1, 0666)) < 0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&perror("failed to semget");
&&&&&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&&&init_sem(sem_id, 0);
&&&&&&&&&&&&&&if ((shmid = shmget(key, sizeof(memory), 0666 | IPC_CREAT | IPC_EXCL)) < 0)
&&&&&&&&&&&&if (errno == EEXIST)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if ((shmid = shmget(key, sizeof(memory), 0666)) < 0)
&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&perror("failed to create share memory");
&&&&&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&perror("failed to shmget");
&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&}
&&&&&&&&else
&&&&&&&&&&&&create_flag = 1;
&&&&&&&&&&&&&&if ((p = shmat(shmid, NULL, 0)) == (void *)(-1))
&&&&&&&&&&&&perror("failed to shmat");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&&&&&while(1)
&&&&&&&&&&&&sem_p(sem_id);
&&&&&&&&&&&&&&&&&&if (strncmp(p->buf, "quit", 4) == 0)
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&&&&&&&printf("recv: %s\n", p->buf);
&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&if (create_flag == 1)
&&&&&&&&&&&&if (shmdt(p) < 0)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&perror("failed to shmdt");
&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&if (shmctl(shmid, IPC_RMID, NULL) == -1)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&perror("failed to delete share memory");
&&&&&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&delete_sem(sem_id);
&&&&&&&&&&&&&&return 0;
&&&&}信号量的封装:#include <stdio.h>
&&&&#include <stdlib.h>
&&&&#include <sys/types.h>
&&&&#include <sys/ipc.h>
&&&&#include <sys/sem.h>
&&&&#include <unistd.h>
&&&&&&&&&&void init_sem(int , int );
&&&&void delete_sem(int );
&&&&void sem_p(int );
&&&&void sem_v(int );
&&&&&&&&&&union semun
&&&&&&&&int val;
&&&&&&&&struct semid_ds *buf;
&&&&&&&&unsigned short *array;
&&&&&&&&&&void init_sem(int sem_id, int init_value)
&&&&&&&&union semun sem_union;
&&&&&&&&&&&&&&sem_union.val = init_value;
&&&&&&&&&&&&&&if (semctl(sem_id, 0, SETVAL, sem_union) < 0)
&&&&&&&&&&&&perror("failed to init_sem");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&return ;
&&&&&&&&&&void delete_sem(int sem_id)
&&&&&&&&union semun sem_union;
&&&&&&&&&&&&&&if (semctl(sem_id, 0, IPC_RMID, sem_union) < 0)
&&&&&&&&&&&&perror("failed to delete_sem");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&return ;
&&&&&&&&&&void sem_p(int sem_id)
&&&&&&&&struct sembuf sem_b;
&&&&&&&&&&&&&&sem_b.sem_num = 0;
&&&&&&&&sem_b.sem_op = -1;
&&&&&&&&sem_b.sem_flg = SEM_UNDO;
&&&&&&&&&&&&&&if (semop(sem_id, &sem_b, 1) < 0)
&&&&&&&&&&&&perror("failed to sem_p");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&return;
&&&&&&&&&&void sem_v(int sem_id)
&&&&&&&&struct sembuf sem_b;
&&&&&&&&&&&&&&sem_b.sem_num = 0;
&&&&&&&&sem_b.sem_op = 1;
&&&&&&&&sem_b.sem_flg = SEM_UNDO;
&&&&&&&&&&&&&&if (semop(sem_id, &sem_b, 1) < 0)
&&&&&&&&&&&&perror("failed to sem_v");
&&&&&&&&&&&&exit(-1);
&&&&&&&&&&&&&&return ;
阅读(1116) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~
请登录后评论。java进程间通信如何实现共享内存与信号量结合使用
[问题点数:40分,结帖人tomorrowzls]
java进程间通信如何实现共享内存与信号量结合使用
[问题点数:40分,结帖人tomorrowzls]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|博客访问: 425188
博文数量: 133
博客积分: 3207
博客等级: 中校
技术积分: 1890
注册时间:
认证徽章:
分类: LINUX 14:47:27
信号量是一个计数器,常用于处理进程和线程的同步问题,特别是对临界资源访问的同步。获取一次信号量的操作就是对信号量减一,而释放一次信号量的操作就是对信号量加一。Linux内核为每个信号集提供了一个semid_ds数据结构.该结构定义如下(linux/sem.h):/* Obsolete, used only for backwards compatibility and libc5 compiles */struct&semid_ds&{&&&&struct&ipc_perm&&&&sem_perm;&&&&&&&&/* 对信号操作的许可权 */&&&&__kernel_time_t&&&&sem_otime;&&&&&&&&/*对信号操作的最后时间 */&&&&__kernel_time_t&&&&sem_ctime;&&&&&&&&/*对信号进行修改的最后时间 */&&&&struct&sem&&&&*sem_base;&&&&&&&&/*指向第一个信号 */&&&&struct&sem_queue&*sem_pending;&&&&&&&&/* 等待处理的挂起操作 */&&&&struct&sem_queue&**sem_pending_last;&&&&/* 最后一个正在挂起的操作 */&&&&struct&sem_undo&&&&*undo;&&&&&&&&&&&&/* 撤销的请求 */&&&&unsigned&short&&&&sem_nsems;&&&&&&&&/* 数组中的信号数 */};(1)Linux下使用系统函数创建和打开信号集.这个函数定义在头文件sys/sem.h中,函数原型如下:int semget(key_t key, int nsems, int semflg);该函数执行成功则返回一个信号集的标识符,失败返回-1。函数第一个参数由ftok()得到键值。第二个参数nsems指明要创建的信号集包含的信号个数,如果只是打开信号集,把nsems设置为0即可;第三个参数semflg为操作标志,可以取如下值。IPC_CREAT:调用semget时,它会将此值与其他信号集的key进行比较,如果存在相同的Key,说明信号集已经存在,此时返回给信号集的标识符,否则新建一个信号集并返回其标识符。IPC_EXCL:该宏须和IPC_CREAT一起使用。使用IPC_CREAT|IPC_EXCL时,表示如果发现信号集已经存在,则返回错误,错误码是EEXIST。(2)信号量的操作,信号量的值和相应资源的使用情况有关,当它的值大于0时,表示当前可用资源的数量,当它的值小于0时,其绝对值表示等待使用该资源的进程个数.信号量的值仅能由PV操作来改变。在Linux下,PV操作通过调用函数semop实现。该函数定义在文件/sys/sem.h,原型如下:int semop(int semid, struct sembuf *sops, size_t nsops);参数semid为信号集的标识符;参数sops指向进行操作的结构体数组首地址;参数nsops指出将要进行操作的信号的个数。semop函数调用成功返回0,否则返回-1.sops参数的定义如下:(linux/sem.h)struct &sembuf {&& & & &ushort &sem_ //信号在信号集的索引&& & & &short & sem_ &//操作类型&& & & &short & sem_ //操作标志};
&sem_op的取值和意义
&sem_op > 0
&信号加上sem_op.表示进程释放控制的资源
&sem_op = 0
&如果没有设置IPC_NOWAIT,则进程进入睡眠,直到信号值为0;否则进程不会睡眠,直接返回EAGAIN
&sem_op < 0
信号加上sem_op的值,若没有设置IPC_NOWAIT,则进程进入睡眠,直到资源可用。否则直接返回EAGAIN&
(3)信号量的控制,使用信号量时,往往需要对信号集进行一些控制操作,比如删除信号集、对内核维护的信号集的数据结构semid_ds进行设置,获取信号集中信号值等。通过semctl可以操作:(sys/sem.h)int semctl(int semid, int semnum, int cmd,...);函数中,参数semid为信号集的标识符,参数semnum标识一个特定的信号;cmd指明控制操作的类型。最后的“...”说明函数的参数是可选的,它依赖于第3个参数cmd,它通过共用体变量semun选择要操作的参数.semun定义在Linux/sem.h:/* arg for semctl system calls. */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 */&&&&void&*__pad;};以上各个字段含义如下:1)val:仅用于SETVAL操作类型,设置某个信号的值等于val2)buf:用于IPC_STAT和IPC_SET,存取semid_ds结构3)array:用于SETALL和GETALL操作4)buf:为控制IPC_INFO提供的缓存cmd的宏含义如下:IPC_SET:对信号量的属性进行设置IPC_RNID:删除semid指定的信号集GETPID:返回最后一个执行semop操作的进程IDGETVAL:返回信号集semnum指定信号的值。GETALL:返回信号集中所用信号的值.GETNCNT:返回正在等待资源的进程的数量.GETZCNT:返回正在等待完全空闲资源的进程的数量.SETVAL:设置信号集中semnum指定的信号的值SETALL:设置信号集中所用信号的值.共享内存:共享内存就是分配一块能被其它进程访问的内存。每个共享内存段在内核中维护着一个内部结构shmid_ds:(linux/shm.h)/* Obsolete, used only for backwards compatibility and libc5 compiles */struct&shmid_ds&{&&&&struct&ipc_perm&&&&&&&&shm_perm;&&&&/* 操作许可 */&&&&int&&&&&&&&&&&&shm_segsz;&&&&/* 共享内存大小,字节为单位 */&&&&__kernel_time_t&&&&&&&&shm_atime;&&&&/* 最后一个进程访问共享内存的时间 */&&&&__kernel_time_t&&&&&&&&shm_dtime;&&&&/* 最后一个进程离开共享内存的时间 */&&&&__kernel_time_t&&&&&&&&shm_ctime;&&&&/* 最后一次修改共享内存的时间 */&&&&__kernel_ipc_pid_t&&&&shm_cpid;&&&&/* 创建共享内存的进程ID */&&&&__kernel_ipc_pid_t&&&&shm_lpid;&&&&/* 最后操作共享内存的进程ID */&&&&unsigned&short&&&&&&&&shm_nattch;&&&&/* 当前使用该贡献内存的进程数量 */&&&&unsigned&short&&&&&&&&&shm_unused;&&&&/* compatibility */&&&&void&&&&&&&&&&&&&*shm_unused2;&&&&/* ditto - used by DIPC */&&&&void&&&&&&&&&&&&*shm_unused3;&&&&/* unused */};(1)创建共享内存:(linux/shm.h)int shmget(key_t key, size_t size, int shmglf);参数key和shmflg可以参考semflg的参数。size是以字节为单位指定的内存的大小。(2)共享内存的操作:(linux/shm.h)void *shmat (int shmid, const void *shmaddr, int shmflg);在使用共享内存前,必须通过shmat函数将其附加到进程的地址空间。shmat调用成功后会返回一个指向共享内存区域的指针,使用该指针就可以访问共享内存了。如果失败返回-1。shmat参数shmid是shmget的返回值。参数shmflg为存取权限标志;参数shmaddr为共享内存的附加点。参数shmaddr不同取值情况说明如下:1)如果为空,则由内核选取一个空闲的内存区;否则,返回地址取决于调用者是否给shmflg设置了SHM_RND值,如果没有指定,则共享内存区附加到由shmaddr指定的地址,否则附加地址为shmaddr向下舍入一个共享内存底端边界地址后的地址。当进程结束使用共享内存时,要通过函数断开与共享内存的链接。(sys/shm.h):int shmdt(const void *shmaddr);参数shmaddr为shmat的返回值,该函数调用成功后,返回0,否则返回-1。(3)共享内存的控制。(sys/shm.h):int shmctl(int shmid, int cmd, struct shmid_ds *buf);参数shmid为共享内存区的标识符,即shmget函数的返回值.buf是指向shmid_ds结构体的指针;cmd为操作标志位,支持以下3种操作:1)IPC_RMID : 从系统中删除由shmid指向的共享内存区2)IPC_SET:设置共享内存的shmid_ds结构3)IPC_STAT:读取共享内存区的shmid_ds机构,并将其存储到buf指向的地址。这里是以简单的读者和写者为例,来学习信号量和共享内存。整个程序的设计规定如下:1、首先让写者获取信号量,去写临界区,这是的临界区就是共享内存。完成后释放掉信号量。2、当读者获取信号量后,就去读临界区的数据,读出数据完成后,释放掉信号量。以上读者和写者分别是两个进程,代码如下:src/shm_write.c (写者代码):#include "shm_mem.h"
int main(int argc, char** argv)
&&&&int semid, shmid;
&&&&char write_str[SHM_SIZE];
&&&&char *ret;
&&&&if((shmid = creatshm(".", 57, SHM_SIZE)) == -1) //创建或者获取共享内存
&&&&&&&&return -1;/*建立进程和共享内存连接*/
&&&&if((shmaddr = shmat(shmid, (char*)0, 0)) == (char *)-1){
&&&&&&&&perror("attch shared memory error!\n");
&&&&&&&&exit(1);
&&&&if((semid = creatsem("./", 39, 1, 1)) == -1)//创建信号量
&&&&&&&&return -1;
&&&&while(1){
&&&&&&&&wait_sem(semid, 0);//等待信号量可以被获取
&&&&&&&&sem_p(semid, 0); &//获取信号量/***************写共享内存***************************************************/
&&&&&&&&printf("write : ");
&&&&&&&&ret = fgets(write_str, 1024, stdin);
&&&&&&&&if(write_str[0] == '#') // '#'结束读写进程
&&&&&&&&&&&&break;
&&&&&&&&int len = strlen(write_str);
&&&&&&&&write_str[len] = '\0';
&&&&&&&&strcpy(shmaddr, write_str);/****************************************************************************/
&&&&&&&&sem_v(semid, 0); //释放信号量
&&&&&&&&usleep(1000); &//本进程睡眠.
&&&&sem_delete(semid); //把semid指定的信号集从系统中删除
&&&&deleteshm(shmid);&& //从系统中删除shmid标识的共享内存
&&&&return 0;
}src/shm_read.c (读者代码):#include "shm_mem.h"
int main(int argc, char** argv)
&&&&int semid, shmid;
&&&&printf("What!!!!!!!!!!!\n");
&&&&if((shmid = creatshm(".", 57, SHM_SIZE)) == -1)
&&&&&&&&return -1;
&&&&if((shmaddr = shmat(shmid, (char*)0, 0)) == (char *)-1){
&&&&&&&&perror("attch shared memory error!\n");
&&&&&&&&exit(1);
&&&&if((semid = opensem("./", 39)) == -1)
&&&&&&&&return -1;
&&&&printf("read start....................\n");&&&&&&&&
&&&&while(1){
&&&&&&&&printf("read : ");
&&&&&&&&wait_sem(semid, 0); &//等待信号量可以获取
&&&&&&&&if(sem_p(semid, 0) == -1) 获取信号量失败退出。当写者写入'#'时表示退出
&&&&&&&&&&&&break;
&&&&&&&&printf("%s", shmaddr);
&&&&&&&&sem_v(semid, 0);
&&&&&&&&usleep(1000);
&&&&return 0;
}shm_mem.h:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <error.h>
#define SHM_SIZE &&&&1024
union semun{
&&&&int val;
&&&&struct semid_ds
&&&&unsigned short
&&&&struct seminfo
*buf_info;
/* 创建信号量函数*/
int creatsem(const char *pathname, int proj_id, int members, int init_val)
index, sid;
&&&&union semun
&&&&if((msgkey = ftok(pathname, proj_id)) == -1){
&&&&&&&&perror("ftok error!\n");
&&&&&&&&return -1;
&&&&if((sid = semget(msgkey, members, IPC_CREAT|0666)) == -1){
&&&&&&&&perror("semget call failed.\n");
&&&&&&&&return -1;
&&&&semopts.val = init_val;
&&&&for(index = 0; index < members; index++){
&&&&&&&&semctl(sid, index, SETVAL, semopts);
&&&&return
int opensem(const char *pathname, int proj_id)
&&&&int sid;
&&&&if((msgkey = ftok(pathname, proj_id)) == -1){
&&&&&&&&perror("ftok error!\n");
&&&&&&&&return -1;
&&&&if((sid = semget(msgkey, 0, 0666)) == -1){
&&&&&&&&perror("open semget call failed.\n");
&&&&&&&&return -1;
&&&&return sid;
/* p操作, 获取信号量*/
int sem_p(int semid, int index)
&&&&//struct sembuf sbuf = {0, -1, SEM_UNDO};
&&&&struct sembuf sbuf = {0, -1, IPC_NOWAIT};
&&&&if(index < 0){
&&&&&&&&perror("index of array cannot equals a minus value!\n");
&&&&&&&&return -1;
&&&&sbuf.sem_num = index;
&&&&if(semop(semid, &sbuf, 1) == -1){
&&&&&&&&perror("A wrong operation to semaphore occurred!\n");
&&&&&&&&return -1;
&&&&return 0;
/* V操作, 释放信号量*/
int sem_v(int semid, int index)
&&&&//struct sembuf sbuf = {0, 1, SEM_UNDO};
&&&&struct sembuf sbuf = {0, 1, IPC_NOWAIT};
&&&&if(index < 0){
&&&&&&&&perror("index of array cannot equals a minus value!\n");
&&&&&&&&return -1;
&&&&sbuf.sem_num = index;
&&&&if(semop(semid, &sbuf, 1) == -1){
&&&&&&&&perror("A wrong operation to semaphore occurred!\n");
&&&&&&&&return -1;
&&&&return 0;
/* 删除信号量几*/
int sem_delete(int semid)
&&&&return (semctl(semid, 0, IPC_RMID));
/* 等待信号量为1*/
int wait_sem(int semid, int index)
&&&&while(semctl(semid, index, GETVAL, 0) == 0)
&&&&&&&&//wait_num++;
&&&&&&&&usleep(500);
&&&&//printf("wait_num = %x\n", wait_num);
&&&&return 1;
/* 创建共享内存*/
int creatshm(char *pathname, int proj_id, size_t size)
&&&&if((shmkey = ftok(pathname, proj_id)) == -1){
&&&&&&&&perror("ftok error!\n");
&&&&&&&&return -1;
&&&&if((sid = shmget(shmkey, size, IPC_CREAT|0666)) == -1){
&&&&&&&&perror("shm call failed!\n");
&&&&&&&&return -1;
&&&&return sid;
/* 删除共享内存*/
int deleteshm(int sid)
&&&&void *p = NULL;
&&&&return (shmctl(sid, IPC_RMID, p));
阅读(9876) | 评论(4) | 转发(1) |
给主人留下些什么吧!~~
想不明白为什么要定义wait_sem函数呢?信号量本来就是阻塞性的,为了节约CPU资源,是有别于自旋锁的,而wait_sem函数内却设置成while死循环无限等待,不就失去了信号量本来的作用了吗?这里是否有其他我没有想到的意图呢?麻烦作者看到后回复我一下
在shm_mem.h里的int creatsem(const char *pathname, int proj_id, int members, int init_val)函数里修改如下:
union semun semopts_x;
这个是头文件的问题,请看下面的文章:
http://topic.csdn.net/t//4880830.html
谢谢你的代码 ,但我运行的时候有个错,
error: storage size of ‘semopts’ isn’t known??
请登录后评论。unix/linux IPC机制对象(如:信号量,共享内存等),为什么没有引用计数?应该怎么使用这些对象? - 知乎28被浏览718分享邀请回答21 条评论分享收藏感谢收起写回答}

我要回帖

更多关于 共享内存与信号量 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信