linux进程间通信学习总结(完)

无名管道

命名管道

消息队列

共享内存

信 号

信号量

1,无名管道
函数pipe()
头文件
#include <unistd.h>
函数原型
int pipe(int pipefd[2]);
pipefd[2]:定义个整型数组其中pipefd[1]为读,pipefd[2]为写,一个进程只能读或则只能写(父与子通信)
return:成功为0,错误为-1
2,命名管道
函数原型mkfifo [OPTION] 例如 mkfifo(“./file”,0600)
file:创建的管道文件名称
0600:权限
使用文件进行两个进程之间的通信
return :错误为-1
3,消息队列
主要用到5个api
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
a,ftok() (创建key值)
函数原型:key_t ftok(const char *pathname, int proj_id);
const char *pathname:一般为“.”,.代表当前文件路径。
int proj_id :一般为任意一个数字(6)或则字符(‘z’)
return:会生成一个key值。
b,msgget()(创建消息队列)
函数原型:int msgget(key_t key, int msgflg);
key:由ftok()函数生成的一个key值
int msgflg:一般为IPC_CREAT|0777。创建管道加权限
return:为一个消息队列号
c,msgsnd()函数 (发送消息)
函数原型int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
int msqid:为消息队列号
const void msgp:是一个结构体:初始化结构体
struct msgbuf {
long mtype; /
message type, must be > 0 /发送的数据类型
char mtext[1]; /
message data */发送的内容
};
size_t msgsz:发送的内容的大小
int msgflg:一般为0,意思为非阻塞
D,msgrcv()函数(接收消息)
函数原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
int msqid:为消息队列号
void msgp:
struct msgbuf {
long mtype; /
message type, must be > 0 /
char mtext[1]; /
message data */
};
size_t msgsz:接收的内容的大小
long msgtyp:接收的数据类型
int msgflg:一般为0,意思为阻塞
E,msgctl()可以删除消息队列

函数原型int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msqid:为消息队列号
int cmd:一般为IPC_RMID
struct msqid_ds *buf:一般为NULL
接收然后在发送例子

#include<string.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>


struct msgbuf
{
   long mtype;      
   char mtext[128];    
};





int main()
{

	struct   msgbuf  readBuf;
	 struct   msgbuf  sendBuf = {999,"this is cool"};

	int key = ftok(".", 'a');

        printf("key = %d\n",key);

	int msgID = msgget(key,IPC_CREAT|0777);
	
	if(msgID == -1){
				printf("creat pipe failing\n");
				
				}
	
	int ret  = msgrcv(msgID, &readBuf, sizeof(readBuf), 888,0);
	
	if(ret != -1){

	printf("receive successfully\n");
	printf("from another processing:%s\n",readBuf.mtext);
		sleep(3);
			}
		
	int ret1 = msgsnd(msgID, &sendBuf, strlen(sendBuf.mtext),0);
	  if(ret1 == 0){
                                        printf("send successfully\n");
                                                }

	msgctl(msgID,IPC_RMID,NULL);

	return 0;
}
发送在接收
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<string.h>
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);


struct msgbuf
{
   long mtype;       /* message type, must be > 0 */
   char mtext[128];    /* message data */
};





int main()
{

	struct   msgbuf  sendBuf = {888,"this is mine"};
	struct msgbuf readbuf;

	int key = ftok(".", 'a');

	printf("key =%d \n",key);

	int msgID = msgget(key,IPC_CREAT|0777);
	
	if(msgID == -1){
				printf("creat pipe failing\n");
				
				}
	int ret = msgsnd(msgID, &sendBuf, strlen(sendBuf.mtext),0);
		
		if(ret == 0){
					printf("send successfully\n");
						sleep(3);
						}
	msgrcv(msgID, &readbuf, sizeof(readbuf), 999,0);
 if(ret != -1){
		 printf("receive successfully\n");
        printf("from another processing:%s\n",readbuf.mtext);
                        }      
	 msgctl(msgID,IPC_RMID,NULL);

return 0;
}

4,共享内存
5个api: ftok(),shmget(),shmat(),shmctl(),shmdt()
A,ftok()同上面消息队列是一致的
B,shmget():打开或创建共享内存
头文件
#include <sys/types.h>
#include <sys/shm.h>
函数原型
int shmget(key_t key, size_t size, int shmflg);
size_t size:共享内存大小
shmflg:共享内存大小
return:为共享内存的标识符
C,shmat(),shmdt():映射
头文件
#include <sys/types.h>
#include <sys/shm.h>
函数原型
void *shmat(int shmid, const void *shmaddr, int shmflg);挂载
shmid:共享内存标识符
shmaddr: 一般为0,系统自动分配内存
shmflg:标志位一般为0,可读可写
shmat()的返回值:为挂载到该进程的地址用一个字符指针来接收
int shmdt(const void *shmaddr);切断挂载
shmaddr:shmat()的返回值
D,shmctl()删除共享内存和共享队列一样

注:ipcs -m 查找当前的共享内存
ipcrm±m+共享内存号(删除该共享内存)(+为空格)

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

int main()
{
//       int shmget(key_t key, size_t size, int shmflg);
	key_t key;
	int getshare;
	char *shm;
	
	 key = ftok(".",1);

	getshare = shmget(key,1024*4,IPC_CREAT|0666);

  	shm = shmat(getshare,0,0);
	
	strcpy(shm,"shandsome");
	
	sleep(5);
	shmdt(shm);

	shmctl(getshare,IPC_RMID,0);

	return 0;
}#include<stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdlib.h>

int main()
{
//       int shmget(key_t key, size_t size, int shmflg);
	key_t key;
	int getshare;
	char *shm ;
	key  = ftok(".",1);

	getshare = shmget(key,1024*4,0);

  	shm =	shmat(getshare,0,0);
	
	printf("%s\n",shm);

	shmdt(shm);

	return 0;
}

5,信号
见文章 https://www.jianshu.com/p/f445bfeea40a

例程

#include<stdio.h>
#include <signal.h>
  #include <sys/types.h>
       #include <unistd.h>

//       int sigaction(int signum, const struct sigaction *act,
//                     struct sigaction *oldact);

void handler(int signum, siginfo_t *info, void *context)
{
	printf("get signum:%d\n",signum);
	if(context != NULL){
				printf("get data = %d\n",info->si_int);
				
				printf("get data = %d\n",info->si_value.sival_int);
	
				printf("from another process:%d\n",info->si_pid);
				}


	
}




int main()
{
	struct sigaction act;
	printf("this process:%d\n",getpid());
	act.sa_sigaction = handler;
	act.sa_flags =  SA_SIGINFO;

	sigaction(SIGUSR1,&act,NULL);	
        while(1);
	return 0;
}

#include<stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

 //      int sigqueue(pid_t pid, int sig, const union sigval value);


int main(int argc,char **argv)
{
	int signum = atoi(argv[1]);
	int pid = atoi(argv[2]);

	union sigval value;

	value.sival_int = 100;
	sigqueue(pid,signum,value);
	printf("pid=%d\n",getpid());

	return 0;

}

信号和共享内存的使用
接收

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

void sigusr1_handler(int signum, siginfo_t *info, void *context) {
    // 信号处理函数仅用于标记信号已接收
    printf("SIGUSR1 received.\n");
}

int main() {
    struct sigaction sa;
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = &sigusr1_handler;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGUSR1, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("Receiver process started. PID: %d\n", getpid());

    // 创建和附加共享内存
    key_t key = ftok("shmfile", 65); 
    int shmid = shmget(key, 1024, 0666|IPC_CREAT); 
    char *str = (char*) shmat(shmid, (void*)0, 0); 

    // 等待信号
    pause();

    // 读取共享内存中的数据
    printf("Data received: %s\n", str);

    // 分离和销毁共享内存
    shmdt(str);
    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}

发送

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>

int main() {
    key_t key = ftok("shmfile", 65);
    int shmid = shmget(key, 1024, 0666|IPC_CREAT); 
    char *str = (char*) shmat(shmid, (void*)0, 0); 

    printf("Writing to shared memory: \"Hello, World!\"\n");
    strncpy(str, "Hello, World!", 1024);

    pid_t pid; 
    printf("Enter the PID of the receiver process: ");
    scanf("%d", &pid);

    union sigval value;
    value.sival_int = 0; 

    if (sigqueue(pid, SIGUSR1, value) == -1) {
        perror("sigqueue");
    }

    // 等待接收进程读取数据
    sleep(5);

    shmdt(str);
    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}

6,信号量
3个api
semget(),semctl(),semop()

#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

//       int semget(key_t key, int nsems, int semflg);
 union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };

void pGetkey(int id)
{
// int semop(int semid, struct sembuf *sops, unsigned nsops);
	struct sembuf set;
	
	set.sem_num = 0;
	
	set.sem_op = -1;
	
	set.sem_flg = SEM_UNDO;
	
	semop(id,&set,1);

	printf("get  the key\n");
	

}

void vputkey(int id)
{
// int semop(int semid, struct sembuf *sops, unsigned nsops);
// semid:信号量id。sops设置信号量放下参数。nsops:信号量个数
        struct sembuf set;

        set.sem_num = 0;

        set.sem_op = 1;

        set.sem_flg = SEM_UNDO;

        semop(id,&set,1);

        printf("put back the key\n");


}


int main()
{
	key_t key;
	
	key = ftok(".",2);
	
	int semid;

	semid = semget(key,1,IPC_CREAT|0666);//创建信号量
	
	union semun  initsem;
	initsem.val = 0;

// int semctl(int semid, int semnum, int cmd, ...);
//  semnum:操作第几个信号量
	semctl(semid,0,SETVAL,initsem);//初始化信号量

	int pid = fork();
	if(pid > 0){
			 pGetkey(semid);
                  printf("this is father\n");
                  vGetkey(semid);

				
			}

	else if(pid == 0)	
	{
		vputkey(semid);
		printf("this is son\n");
		
			}



	return 0;

}

师上官可编程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值