进程间的通信相关函数

LINUX 进程间通信方式:

传统:
有名管道:mkfifo write read close
无名管道:pipe write read close
信号: signal kill raise pause alarm
POSIX:
信号量:
有名:sem_open sem_close sem_unlink
无名:sem_init sem_destroy
sem_post sem_wait sem_getvalue
共享内存:
shm_open shm_unlink   shm_overview mmap munmap
消息队列:
mq_open mq_close mq_unlink mq_send mq_receive
system V:
信号量集:
semget semctl semop
共享内存:
shmget shmctl shmat shmop
消息队列:
msgget msgop msgctl msgsnd msgrcv
BSD:
连接:
SERVER: socket bind listen accept recv send
CLIENT: socket bind connect send recv
无连接:
SERVER: socket bind recvfrom sendto
CLIENT: socket bind sendto recvfrom
一、管道
①无名管道 
只能用于具有亲缘关系的进程间的通信;是一种半双工的通信方式,具有固定的读端和写端
创建:int pipe(int fd[2])
@fd[2]为包含两个元素的整形数组,传参传入数组名即可
返回值:成功返回0,出错返回-1
读写:管道可以看成一种特殊的文件,对于它的读写可以使用文件IO如:read、write
具有固定的读端口fd[0]       写端口fd[1]
关闭:close
注意:
当管道为空时堵塞读端,知道写入为止
当管道为满时堵塞写端,直到读走为止
当管道所有读端关闭,往里写时则直接发送SIGNAL杀死进程
当管道所有写端关闭,往外读时,读出内容并返回0,此时并不堵塞管道
②有名管道
有名管道可以在两个互不关联的进程间进行通信;通过路径名指出并且在系统中可见
创建:int mkfifo(const char *path,mode_t mode)
@path:创建管道的存储路径及管道名
@mode;权限0666
成功返回0 失败返回-1
读写,关闭都是通过文件IO完成的
③信号
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式,
可以直接进行用户进程与内核进程之间的交互
信号的发送:
int kill(pid_t pid,int sig)
@pid 进程号
@sig 信号
成功返回 0   失败返回-1
raise(int sig)向自己发送信号
pause()     将自己进入堵塞态
alam(int second)   定时一段时间
typedef void (*aftersig) (int)   将void(*)(int)重定义为 aftersig
绑定信号aftersig   signal(int sig,aftersi fan)
fan是一个回调函数当sig 信号发生时fan被触发
④共享内存
#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)
#define EADDR ((void *)-1)                
#define KEY_FILE "./shmopt.c"

#define SHMADDR ((void *)0XA0001000)

int main()
{
int shmid;
key_t key;
char *memaddr = NULL;

key = ftok(KEY_FILE, 0xac);                                     //生成key 值

if (-1 == (shmid = shmget(key, PAGE_SIZE, IPC_CREAT | 0666)))   //申请共享内存空间
error_exit("shmget");

printf("%d\n", shmid);

if (EADDR == (memaddr = shmat(shmid, SHMADDR, SHM_RND)))     绑定内存空间返回值为内存首地址
error_exit("shmat");

printf("%p\n", memaddr);
#if 0
printf("b: %s\n", memaddr);

strcpy(memaddr, "hellowrld");
printf("a: %s\n", memaddr);
#endif
if (-1 == shmdt(memaddr))                           //使用完毕解除绑定
error_exit("shmdt");

if (-1 == shmctl(shmid, IPC_RMID, NULL))           //删除共享内存
error_exit("shmctl");

return 0;
}
⑤消息队列
#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)
#define IPC_KEY 0X01020304
#define KEY_FILE "."
#define KEY_MAGIC 'A'

typedef struct _msgbuf_ {
long type;
char buff[128];
}msgbuf_st;                                 定义一个消息包,

int main()
{
int msgid;
msgbuf_st msgbuf;

if (-1 == (msgid = msgget(IPC_KEY, IPC_CREAT | 0666)))   创建消息队列
error_exit("msgget");

msgbuf.type = 1;
strcpy(msgbuf.buff, "helloworld");

#if 0
if (-1 == msgsnd(msgid, &msgbuf, strlen(msgbuf.buff)+1, 0))         发送消息
error_exit("msgsnd");
#endif
#if 0
memset(&msgbuf, 0, sizeof(msgbuf));
if (-1 == msgrcv(msgid, &msgbuf, sizeof(msgbuf), 2, 0))               接收消息
error_exit("msgrcv");
printf("type: %ld\ninfo: %s\n", msgbuf.type, msgbuf.buff);

#endif

if (-1 == msgctl(msgid, IPC_RMID, NULL))                             删除消息队列
error_exit("msgctl");
return 0;
}
⑥信号量集
#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)
#define IPC_KEY 0X01020304
#define KEY_FILE "."
#define KEY_MAGIC 'A'

#define SEMNUMS 2

int main()
{
int semid;
int semval;
unsigned short semarry[SEMNUMS];


if (-1 == (semid = semget(IPC_KEY, SEMNUMS,IPC_CREAT | 0666)))       创建
error_exit("semget");

 
if (-1 == semctl(semid, 0, SETVAL, 10))                         初始化0号信号为10
error_exit("semctl.SETVAL");

if (-1 == (semval = semctl(semid, 0, GETVAL)))                 查看信号0号信号
error_exit("semctl.GETVAL");
printf("semval[0]: %d\n", semval);

#else
semarry[0] = 0;
semarry[1] = 1;
if (-1 == semctl(semid, 0, SETALL, semarry))         初始化所有的信号量
error_exit("semctl.SETVAL");
if (-1 == (semval = semctl(semid, 0, GETALL, semarry)))     查看所有的信号量
error_exit("semctl.GETVAL");
printf("semval[0]: %d\nsemval[1]: %d\n", semarry[0], semarry[1]);


#endif

return 0;
}
PV操作:
#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)
#define IPC_KEY 0X01020304
#define KEY_FILE "."
#define KEY_MAGIC 'A'

#define SEMNUMS 2

int main()
{
int semid;
int semval;
unsigned short semarry[SEMNUMS];
struct sembuf semops;
#if 0
union _semuin_   {
int val;
struct semid_ds *dsbuf;
unsigned short *arrays;
struct seminfo *infobuf;
}semuin = {
.val = 10,
}
#endif

if (-1 == (semid = semget(IPC_KEY, SEMNUMS,IPC_CREAT | 0666)))
error_exit("semget");

#if 0
if (-1 == (semval = semctl(semid, 0, GETVAL)))
error_exit("semctl.GETVAL");
printf("semval[0]: %d\n", semval);

if (-1 == semctl(semid, 0, SETVAL, 10))
error_exit("semctl.SETVAL");

if (-1 == (semval = semctl(semid, 0, GETVAL)))
error_exit("semctl.GETVAL");
printf("semval[0]: %d\n", semval);

#else
if (-1 == (semval = semctl(semid, 0, GETALL, semarry)))
error_exit("semctl.GETVAL");
printf("semval[0]: %d\nsemval[1]: %d\n", semarry[0], semarry[1]);
semarry[0] = 0;
semarry[1] = 1;
if (-1 == semctl(semid, 0, SETALL, semarry))
error_exit("semctl.SETVAL");
if (-1 == (semval = semctl(semid, 0, GETALL, semarry)))
error_exit("semctl.GETVAL");
printf("semval[0]: %d\nsemval[1]: %d\n", semarry[0], semarry[1]);

#endif

puts("semops V read ...");

semops.sem_num = 0;
semops.sem_op = 1;
semops.sem_flg = 0;
if (-1 == semop(semid, &semops, 1))
error_exit("semop.P");

puts(" after semops V read ...");

semops.sem_num = 0;
semops.sem_op = -1;
semops.sem_flg = 0;
if (-1 == semop(semid, &semops, 1))
error_exit("semop.P");

puts("after P ...");

if (-1 == semctl(semid, 0, IPC_RMID))
error_exit("semctl.IPC_RMID");

return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值