首页 > 代码库 > 信号量学习 & 共享内存同步

信号量学习 & 共享内存同步

刚刚这篇文章学习了共享内存: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;

 

读、写程序流程如下图所示。

 

信号量学习 & 共享内存同步