2012年10月28日 星期日

ipc(share memory)

[Function]
<shmget>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

key:
      IPC_PRIVATE:產生一個新的共享記憶體分段

size:
      需要共享記憶體的大小 , 因為分配大小皆以page為單位 , 所以如果size = 1~4096 , 則實際上會分配到4k.

shmflag:
      S_IRUSR: 讀記憶體分段
      S_IWUSR: 寫記憶體分段
      IPC_CREAT :確保開啟的記憶體是新的,而不是現存的記憶體.
      | 0666 : 作為校驗 ,  ubuntu要加

<shmat>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);

shmid:
          共享記憶體的id

shmaddr:
     NULL:讓系統自己選擇.

shmflg:
     SHM_RDONLY:唯讀模式
          0:可讀可寫

<shmdt>         
#include <sys/shm.h>
int shmdt(const void *shmaddr);
 
<shmctl>
 #include <sys/ipc.h>
#include <sys/shm.h>
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
 
shmid:
           share memory id
 
cmd:
          IPC_STAT: 從共享記憶體裡,拿 shmid_ds 結構資料給 buf.
          IPC_SET: 從buf 複製到共享記憶體
          IPC_RMID: 砍了共享記憶體
 
buf:
        就暫存區.

[CODE]

<shm_server.c>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/stat.h>
#define shm_size     32
#define PARM IPC_CREAT | 0666
int main(void)
{
    char c;
    int shm_id;
    char *shm_addr, *s;
 key_t key;

 key = 5679;
    if ((shm_id = shmget(key, shm_size, PARM)) < 0) {
        perror("shmget");
        return 0;
    }
    if ((shm_addr = shmat(shm_id, NULL, 0)) == (char *) -1) {
        perror("shmat");
        return 1;
    }
    s = shm_addr;
    for (c = 'a'; c <= 'z'; c++)
        *s++ = c;
    *s = NULL;

    while (*shm_addr != '*'){
        sleep(1);
 }
 
 shmdt(shm_addr);
 shmctl(shm_id , IPC_RMID , NULL);
    return 0;
}
<shm_client.c>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/stat.h>
#define shm_size     32
int main(void)
{
    int shmid;
    key_t key;
    char *shm, *s;
    key = 5679;
    if ((shmid = shmget(key, shm_size , S_IRUSR | 0666)) < 0) {
        perror("shmget");
        return 1;
    }
    if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        return 1;
    }
    for (s = shm; *s != NULL; s++)
        putchar(*s);
    putchar('\n');
    *shm = '*';

 return 0;
}


[編譯]
gcc -o server shm_server.c
gcc -o client shm_client.c
./server &
./client &

最後顯示
 haha@haha-VirtualBox:~/work$ abcdefghijklmnopqrstuvwxyz




沒有留言:

張貼留言