linux查询回显来自哪个进程,Linux进程间通信_IPC方法综述

Outline

- 1.pipe使用框架

- 2.fifo使用框架

- 3.file lock使用框架

-4.semaphore使用框架

-5.shared memory使用框架

-6.memory mapped file使用框架

-7.unix socket使用框架

=============================================================

1. pipe使用框架:

实现 "ls | wc -l"

int pipefd[2];

pipe(pipefd);

if(!fork()) {

close(pipefd[0]);

dup2(pipefd[1], 1);

execlp("ls", "ls", NULL);

exit(0);

} else {

wait(NULL);

close(pipefd[1]);

dup2(pipefd[0], 0);

execlp("wc", "wc", "-l", NULL);

exit(0);

}

注:一般pipe大小为10K

2. fifo使用框架

实现echo writer reader,即writer在fifo中写,reader在fifo中读并回显

writer:

mknod("fifoname", S_FIFO | 0666, 0);

fd = open("fifoname", O_WRONLY);

write(fd, input, sizeof(input));

//unlink("fifoname");

reader:

fd = open("fifoname", O_RDONLY);

read(fd, output, sizeof(output));

printf("%s", output);

注意:若reader先关闭,则writer在执行write时收到sigpipe信号;反之,reader执行reader时返回0.

open在没有读者/写者时候,都见先阻塞,直到第一个读者/写者到来.

3. file lock使用框架

所谓file lock,就是对文件加读/写锁,读写锁的原则是一个文件可以有多个读者(没有写者),但是只能有一个写者(没有读者)。具体到程序即,获取多个读锁不会阻塞,但是获取多个写锁会阻塞;有读者时,获取写锁会阻塞;有写者时,获取读锁会阻塞。

下面这个例子,有参数时,给文件加读锁;无参数时,给文件加写锁。按回车后,释放锁。

/*

* =====================================================================================

*

* Filename: rw_locks.c

*

* Description:

*

* Version: 1.0

* Created: 08/10/11 13:14:57

* Revision: none

* Compiler: gcc

*

* Author: YOUR NAME (),

* Company:

*

* =====================================================================================

*/

#include

#include

#include

#include

int main(int argc, char *argv[])

{

int fd;

struct flock flock;

flock.l_type = F_WRLCK; //锁的模式必须与文件打开模式显适应

flock.l_whence = SEEK_SET;

flock.l_start = 0;

flock.l_len = 0;

flock.l_pid = getpid();

fd = open("tt", O_RDWR);

if (fd == -1) {

perror("open file error");

return -1;

}

if(argc > 1)

flock.l_type = F_RDLCK;

printf("Trying to obtain a %s lock!\n",

flock.l_type == F_RDLCK ? "read_lock" : "write lock");

if (fcntl(fd, F_SETLKW, &flock) == -1) {

perror("fcntl error");

return -1;

}

printf("Got a lock!\n");

printf("Press to release the lock\n");

getchar();

flock.l_type = F_UNLCK; //UNLOCK

if (fcntl(fd, F_SETLK, &flock)) { //F_SETLK 用于解锁,也可用于加锁,但与F_SETLKW的区别在于不会被阻塞,立即返回-1

perror("fcntl error");

return -1;

}

printf("Lock released!\n");

close(fd);

return 0;

}

3. mseeage queue使用框架

ftok("filename", 'A') //存在的文件名加任意int产生key

msgget //IPC_CREAT

msgsnd / msgrcv

//msgctl(id, IPC_RMID, NULL)

注:可存在多个读写者

4. semaphore使用框架

semapore中要特别注意的一点是semaphore set创建以后需要进行初始化(semop),在初始化完成前(通过检查semid_ds中的sem_otime域),其他使用该set的进程需要等待

#include

#include

#include

#include

#include

#include

#include

#define SEMNUM 1

int main(int argc, char *argv[])

{

key_t key;

int semid;

struct sembuf buf = {0, 1, 0};

key = ftok("tt", 'A');

if (key == -1) {

perror("ftok error");

return -1;

}

semid = semget(key, SEMNUM, IPC_CREAT | IPC_EXCL | 0666);

if (semid == -1) {

perror("semget error");

return -1;

}

puts("initialize the semaphore set...");

puts("press to continue");

getchar();

for (buf.sem_num = 0; buf.sem_num < SEMNUM; buf.sem_num++) {

if (semop(semid, &buf, 1) == -1) {

perror("semop error");

semctl(semid, 0, IPC_RMID);

return -1;

}

}

//-----------------------------------

buf.sem_num = 0;

buf.sem_op = -1;

buf.sem_flg = 0;

puts("Acquire a resource");

if (semop(semid, &buf, 1) == -1) {

perror("semop error");

return -1;

}

puts("Resource locked");

puts("Press to unlock");

getchar();

buf.sem_op = 1;

if (semop(semid, &buf, 1) == -1) {

perror("semop error");

return -1;

}

puts("Resource unlocked");

puts("Press to destroy");

getchar();

if (semctl(semid, 0, IPC_RMID) == -1) {

perror("semctl error");

return -1;

}

return 0;

}

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

key_t key;

int semid;

union semun{

int val;

struct semid_ds *buf;

unsigned short *array;

struct seminfo *__buf;

}arg;

struct sembuf buf;

struct semid_ds ds;

key = ftok("tt", 'A');

if (key == -1) {

perror("ftok error");

return -1;

}

semid = semget(key, 1, IPC_CREAT | IPC_EXCL );

puts("waiting for initialization");

if (semid == -1) {

if (errno == EEXIST) {

while(1) {

semid = semget(key, 1, 0666);

if (semid < 0) {

perror("semget error");

return -1;

}

arg.buf = &ds;

if (semctl(semid, 0, IPC_STAT, arg) == -1) {

perror("semctl1 error");

//return -1;

}

if (arg.buf->sem_otime != 0)

break;

}

} else {

perror("semget2 error");

return -1;

}

}

puts("initialization is done");

puts("locking resource");

buf.sem_num = 0;

buf.sem_op = -1;

buf.sem_flg = 0;

if (semop(semid, &buf, 1) == -1) {

perror("semop error");

return -1;

}

puts("Resource locked");

puts("press to unlock");

getchar();

buf.sem_op = 1;

if (semop(semid, &buf, 1) == -1) {

perror("semop error");

return -1;

}

puts("Resource unlocked");

return 0;

}

5. shared memory使用框架

ftok

shmget //IPC_CREAT

data = shmat(id, (void *)0, 0)

//do sth with the return pointer

shmdt

//shmctl(id, IPC_RMID, NULL)

6. memory mapped file使用框架

open

data = mmap((void *)0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)

read / write

munmap(data, statbuf.st_size)

注意,若使用MAP_PRIVATE则各进程分别获取file的一份拷贝,并且最终修改不会写入文件中

7. unix socket使用框架

sockaddr_un local;

local.sun_family = AF_UNIX;

strcpy(local.sun_path, "/a/b/c")

server端

fd = socket(...)

unlink("a/b/c")

bind

listen

newfd = accept

recv / send

close

client端

fd=socket(...)

unlink("/a/b/c")

connect

send / recv

close

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值