信号量+共享内存

一:信号量相关的一些函数

int sem_init(sem_t *sem, int pshared, unsigned int value);

函数功能:

    在地址sem处创建信号量,value为信号量的初始值。成功返回0,失败返回-1

参数:

    sem_t *sem:一个长整形的数,信号量。

    int pshared:零值表示信号量是在线程之间使用,信号量需要能够被所有线程访问。非零值表示信号量在进程之间共享,信号量需要处于共享内存中,进程能够操作访问该共享内存就能通过,sem_post, sem_wait函数对该信号量进行操作。

    unsigned int value:信号量初始值

 

int sem_wait(sem_t *sem);

函数功能:

    如果信号量的值大于0,该放回会将信号量的值减1,如果信号量的值小于等于0,那该函数就会阻塞,直到信号量的值大于等于1为止。成功返回0,失败返回-1.

 

int sem_post(sem_t *sem);

函数功能:

    该函数用于将信号量的值加1,表示其他进程的sem_wait函数可以正常执行了。成功返回0,失败返回-1。

 

int sem_destroy(sem_t *sem);

函数功能:

    对于使用完的信号量进行清理的函数,成功返回0,失败返回-1.

 

二:共享内存相关的一些函数

 (1)

int shmget(key_t key, size_t size, int shmflg);

函数功能:

    创建共享内存,成功返回一个与key相关的共享内存标识符。

参数:

    key:为共享内存命名

    size:以字节为单位,指定共享内存大小

    shmflg:权限标志,作用与open函数的mode参数一样。如果要想在key标识的共享内存不存在时,创建它的话,可以与IPC_CREAT做或操作。共享内存的权限标志与文件的读写权限一样,举例来说,0644,它表示允许一个进程创建的共享内存被内存创建者所拥有的进程向共享内存读取和写入数据,同时其他用户创建的进程只能读取共享内存。

 

 

(2)

void *shmat(int shmid, const void *shmaddr, int shmflg);

用上面的函数创建共享内存后,还不能被其他的任何进程访问。因此该函数就是启动进程对共享内存的访问,把共享内存连接到当前进程的地址空间。

函数功能:

    --at attach  shared memory attach

    字面意思是,共享内存挂接;实现该进程对共享内存的访问。

参数:

    shmid:是由shmget()函数返回的共享内存标识符

    shmaddr:指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。

    shmflg:一组标志位,通常为0

返回值:

    成功,返回指向共享内存第一个字节的指针;失败,返回-1

 

(3)

int shmdt(const void *shmaddr);

函数功能:

    --dt detach 字面意思分离

    将共享内存和当前进程分离,当前进程无法再对共享内存进行访问,但共享内存还存在。

参数:

    shmaddr:shmat 函数调用返回的指针

返回值:

    成功,0;失败,-1

 

(4)

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

函数功能:

    用于控制共享内存

参数:

    shmid:shmget函数得到的共享内存标识符

    cmd:要执行的操作,可以取如下的值。

      IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。

      IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值。

      IPC_RMID:删除共享内存段。

    buf:是一个结构指针,它指向共享内存模式和访问权限的结构。

shmid_ds结构 至少包括以下成员:

struct shmid_ds
{
    uid_t shm_perm.uid;
    uid_t shm_perm.gid;
    mode_t shm_perm.mode;
};

 

 
 

 

三:使用共享内存和信号量的一个例子

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>

typedef struct
{
        int flag;
        int data;
} Data;

int main(int argc,char **argv)
{
        int shm_id,shm_id_1;
        int i;
        pid_t pid;
        sem_t * sem_p;
        Data * share_data_p;
        shm_id = shmget((key_t)1234,sizeof(sem_t),0777|IPC_CREAT);
        sem_p= (sem_t *)shmat(shm_id,0,0);

        if(sem_init(sem_p,123,1) == -1){
                printf("sem_init error!\n");
        }

        shm_id_1 = shmget((key_t)2345,sizeof(Data),0777|IPC_CREAT);
        share_data_p = (Data *)shmat(shm_id_1,0,0);
        memset(share_data_p,0,sizeof(Data));
        for(i=0;i<10;i++){
                pid = fork();
                if(i < 10 && pid > 0){
                        /* write data*/
                        sem_wait(sem_p);
                        share_data_p->flag = 1;
                        share_data_p->data++;
                        sleep(2);
                        printf("data is %d,after ++\n",share_data_p->data);
                        sem_post(sem_p);
                        share_data_p->flag = 0;
                        sleep(3);
                }
                if(pid == 0){
                        while(1){
                                if(share_data_p->flag == 0){
                                   printf("data is %d\n",share_data_p->data);
                                break;
                                }
                        }
                        break;
                }

        }

        return 0;
}

编译时出现,sem_wait未定义时,编译加上 -lpthread

 

posted on 2020-02-16 16:08  andyAngelo  阅读(411)  评论(0)    收藏  举报