linux ipc tools

POSIX IPC为每个对象都使用文件描述符,这与System V的IPC不同,System V的每个对象都使用键值(keys).由于每个IPC对象可以写到一个纯文本文件,因此,在纯文本文件上使用的工具对于操作POSIX IPC对象来说通常已经足够了.1)POSIX共享内存在Linux中,POSIX共享内存对象驻留在tmpfs伪文件系统中.系统默认挂载在/dev/shm目录下.当调用shm_open函数创建或打开POSIX共享内存对象时,系统会将创建/打开的共享内存文件放到/dev/shm目录下.同样也可以手工在/dev/shm目录下创建文件,以供POSIX共享内存程序连接使用.我们用下面的源程序对POSIX共享内存进行测试,如下:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/file.h>#include <sys/mman.h>#include <sys/wait.h>void error_out(const char *msg){ perror(msg); exit(EXIT_FAILURE);}int main (int argc, char *argv[]){ int r; const char *memname = "/mymem"; const size_t region_size = sysconf(_SC_PAGE_SIZE); int fd = shm_open(memname, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd == -1) error_out("shm_open"); r = ftruncate(fd, region_size); if (r != 0) error_out("ftruncate"); void *ptr = mmap(0, region_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) error_out("MMAP"); close(fd); pid_t pid = fork(); if (pid == 0){ u_long *d = (u_long *)ptr; *d = 0xdeadbeef; exit(0); } else{ int status; waitpid(pid, &status, 0); printf("child wrote %#lx\n", *(u_long *)ptr); } sleep(50); r = munmap(ptr, region_size); if (r != 0) error_out("munmap"); r = shm_unlink(memname); if (r != 0) error_out("shm_unlink"); return 0;}编译程序pmem.cgcc pmem.c -o pmem -lrt执行程序pmem./pmemchild wrote 0xdeadbeef注:程序会通过shm_open函数创建一个共享内存对象,并通过mmap函数将文件映射到内存,此时修改内存,即是修改文件.子进程向共享内存写数据,父进程将共享内存数据打印输出,在输出完成后,会等待50秒钟.我们可以在另一个终端看到/dev/shm/mymem文件,如下:ls -l /dev/shm/mymem-rw-r–r– 1 root root 4096 2011-03-16 15:22 /dev/shm/mymem2)POSIX消息队列在Linux中通过mqueue伪文件系统来显示POSIX消息队列,与POSIX共享内存不同的是,它没有一个标准的挂载点来为这个文件系统服务.如果需要调试来自shell的POSIX消息队列,则需要手动挂载文件系统,例如,为了将其挂载在命名为/mnt/mqs的目录下,可以使用以下命令:mkdir /mnt/mqsmount -t mqueue none /mnt/mqs我们用下面的源程序对POSIX消息队列进行测试,如下:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <mqueue.h>#include <sys/stat.h>#include <sys/wait.h>struct message{char mtext[128];};int send_msg(int qid, int pri, const char text[]){int r = mq_send(qid, text, strlen(text) + 1,pri);if (r == -1){perror("mq_send");}return r;}void producer(mqd_t qid){send_msg(qid, 1, "This is my first message.");send_msg(qid, 1, "This is my second message.");send_msg(qid, 3, "No more messages.");}void consumer(mqd_t qid){struct mq_attr mattr;do{u_int pri;struct message msg;ssize_t len;len = mq_receive(qid, (char *)&msg, sizeof(msg), &pri);if (len == -1){ perror("mq_receive"); break;}printf("got pri %d ‘%s’ len=%d\n", pri, msg.mtext, len);int r = mq_getattr(qid, &mattr);if (r == -1){ perror("mq_getattr"); break;}}while(mattr.mq_curmsgs);}intmain (int argc, char *argv[]){struct mq_attr mattr = {.mq_maxmsg = 10,.mq_msgsize = sizeof(struct message)};mqd_t mqid = mq_open("/myq", O_CREAT|O_RDWR, S_IREAD|S_IWRITE, &mattr);if (mqid == (mqd_t) -1){perror("mq_open");exit (1);}pid_t pid = fork();if (pid == 0){producer(mqid);mq_close(mqid);exit(0);}else{int status;wait(&status);sleep(50);consumer(mqid);mq_close(mqid);}mq_unlink("/myq");return 0;}编译:gcc posix_mqs.c -o posix_mqs -lrt运行程序:./posix_mqsgot pri 3 ‘No more messages.’ len=18got pri 1 ‘This is my first message.’ len=26got pri 1 ‘This is my second message.’ len=27注:程序通过fork使子进程发送三条消息到消息队列,父进程从消息队列中接收这三条消息./mnt/mqs/myq文件是程序创建的消息队列文件,程序会自动在伪文件系统mqueue中创建消息队列文件.如果我们挂载伪文件系统到多个目录,而在每个挂载目录下都会生成消息队列文件.例如:mkdir /dev/mqs/mount -t mqueue none /dev/mqsdf -aThFilesystem Type Size Used Avail Use% Mounted on/dev/sda1 ext3 19G 3.3G 15G 19% /proc proc 0 0 0 – /procsysfs sysfs 0 0 0 – /sysdevpts devpts 0 0 0 – /dev/ptstmpfs tmpfs 512M 0 512M 0% /dev/shmnone binfmt_misc 0 0 0 – /proc/sys/fs/binfmt_miscsunrpc rpc_pipefs 0 0 0 – /var/lib/nfs/rpc_pipefsnone mqueue 0 0 0 – /mnt/mqsnone mqueue 0 0 0 – /dev/mqs再次运行程序./posix_mqs我们看到在两个mqueue伪文件系统挂载的目录下都生成了myq文件cat /mnt/mqs/myq /dev/mqs/myqQSIZE:71 NOTIFY:0 SIGNO:0 NOTIFY_PID:0 QSIZE:71 NOTIFY:0 SIGNO:0 NOTIFY_PID:0 QSIZE:71表示/mnt/mqs/myq消息队列中一共有71个字节.NOTIFY,SIGNO,NOTIFY_PID都和mq_notify函数有关.3)POSIX信号量在Linux中,POSIX信号量对象驻留在tmpfs伪文件系统中,同POSIX共享内存一样,有名字的信号量作为文件被创建在/dev/shm里.我们用下面的源程序来测试POSIX信号量,如下:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/file.h>#include <sys/times.h>#include <sys/stat.h>#include <semaphore.h>#include <assert.h>void busywait(void){clock_t t1 = times(NULL);while(times(NULL) – t1 < 2);}int main (int argc, char *argv[]){const char *message = "Hello World\n";int n = strlen(message)/2;sem_t *sem = sem_open("/thesem", O_CREAT, S_IRUSR|S_IWUSR);sleep(30);assert(sem != NULL);int r = sem_init(sem, 1, 0);assert(r == 0);pid_t pid = fork();int i0 = (pid == 0) ? 0 :n ;int i;if (pid)sem_wait(sem);for (i = 0;i < n;i++){write (1,message+i0+i,1);busywait();}if (pid == 0)sem_post(sem);}编译:gcc posix-sem.c -o posix-sem -lrt执行posix-sem程序:./posix-sem在另一个终端查看信号量文件,如下:ls -l /dev/shm/total 4-rw——- 1 root root 16 Mar 18 10:32 sem.thesem一个被命名为thesem的信号量出现在/dev/shm/sem.thesem我想有一天和你去旅行。去那没有去过的地方,

linux ipc tools

相关文章:

你感兴趣的文章:

标签云: