刚刚这篇文章学习了共享内存:http://www.cnblogs.com/charlesblc/p/6142139.html
里面也提到了共享内存,自己不进行同步,需要其他手段比如信号量来进行。那么现在就学习信号量咯。
共享内存实际编程中,
应该使用信号量,
或通过传递消息(使用管道或IPC消息),
或生成信号
的方法来提供读写之间的更有效的同步机制。
方法一、利用POSIX有名信号灯实现共享内存的同步
方法二、利用POSIX无名信号灯实现共享内存的同步
方法三、利用System V的信号灯实现共享内存的同步
方法四、利用信号实现共享内存的同步
信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制。信号灯包括posix有名信号灯、 posix基于内存的信号灯(无名信号灯)和System V信号灯(IPC对象)
方法一、利用POSIX有名信号灯实现共享内存的同步
有名信号量既可用于线程间的同步,又可用于进程间的同步。
两个进程,对同一个共享内存读写,可利用有名信号量来进行同步。一个进程写,另一个进程读,利用两个有名信号量semr, semw。semr信号量控制能否读,初始化为0。 semw信号量控制能否写,初始为1。
读共享内存的程序示例代码如下
semr = sem_open("mysem_r", O_CREAT | O_RDWR , 0666, 0); if (semr == SEM_FAILED) { printf("errno=%d\n", errno); return -1; } semw = sem_open("mysem_w", O_CREAT | O_RDWR, 0666, 1); if (semw == SEM_FAILED) { printf("errno=%d\n", errno); return -1; } if ((shmid = shmget(key, MAXSIZE, 0666 | IPC_CREAT)) == -1) { perror("semget"); exit(-1); } if ((shmadd = (char *)shmat(shmid, NULL, 0)) == (char *)(-1)) { perror("shmat"); exit(-1); } while (1) { em_wait(semr); printf("%s\n", shmadd); sem_post(semw); }
写共享内存的程序示例代码如下
。。。。。。 //同读的程序 while (1) { sem_wait(semw); printf(">"); fgets(shmadd, MAXSIZE, stdin); sem_post(semr); }
方法二、利用POSIX无名信号灯实现共享内存的同步
POSIX无名信号量是基于内存的信号量,可以用于线程间同步也可以用于进程间同步。若实现进程间同步,需要在共享内存中来创建无名信号量。
因此,共享内存需要定义以下的结构体。
typedef struct
{
sem_t semr;
sem_t semw;
char buf[MAXSIZE];
}SHM;
读、写程序流程如下图所示。