(笔记)进程间通讯
进程间通讯
进程间通讯包含五种方式:管道(无名和有名FIFO)、消息队列、信号量、共享内存、Socket(套接字)(支持不同主机间)
参考文章:Linux进程间通信详解(最全)
管道(无名和有名FIFO)
消息队列
由msgget、msgctl、msgsnd、msgrcv四个函数组成。
参考文章:消息队列函数
int Queue_Init(key_t key)
{int msg_id = msgget(key, IPC_CREAT | 0666);if (-1 == msg_id)printf("msgget error!\n");return msg_id;
}int Queue_SendData(int msg_id, void *data, size_t size, int flag)
{int err = msgsnd(msg_id, data, size - sizeof(long), flag);if (-1 == err)printf("msgsnd error!\n");return err;
}int Queue_RecvData(int msg_id, void *data, size_t size, long type, int flag)
{int err = msgrcv(msg_id, data, size - sizeof(long), type, flag);if (-1 == err)printf("msgrcv error!\n");return err;
}int Queue_Delinit(int msg_id)
{int err = msgctl(msg_id, IPC_RMID, NULL);if (-1 == err)printf("msgctl error\n");return err;
}
信号量
参考
共享内存
- 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。
- 因为多个进程可以同时操作,所以需要进行同步。
- 信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问
#define SHM_PATH "/tmp"
typedef struct {size_t size;int shmid;int semid;void *share;
}T_Shm;static void shm_lock(T_Shm *shm)
{struct sembuf sops = {.sem_num = 0,.sem_op = -1,.sem_flg = SEM_UNDO};semop(shm->semid, &sops, 1);
}static void shm_unlock(T_Shm *shm)
{struct sembuf sops = {.sem_num = 0,.sem_op = 1,.sem_flg = SEM_UNDO};semop(shm->semid, &sops, 1);
}int Shm_Init(T_Shm *shm, size_t size)
{key_t key = ftok(SHM_PATH, 1);if (-1 == key) return -1;int shm_id = shmget(key, size, 0666 | IPC_CREAT);if (-1 == shm_id) return -1;int sem_id = semget(key, 1, 0666 | IPC_CREAT);if (-1 == sem_id) return -1;int err = semctl(sem_id, 0, SETVAL, 1);if (-1 == err) return -1;void *data = shmat(shm_id, NULL, 0);if (data == (void *)-1) return -1;shm->semid = sem_id;shm->shmid = shm_id;shm->size = size;shm->share = data;return 0;
}int Shm_SetData(T_Shm *shm, const void *data)
{if (NULL == data) return -1;shm_lock(shm);memcpy(shm->share, data, shm->size);shm_unlock(shm);return 0;
}int Shm_GetData(T_Shm *shm, void *data)
{if (NULL == data) return -1;shm_lock(shm);memcpy(data, shm->share, shm->size);shm_unlock(shm);return 0;
}int Shm_Delinit(T_Shm *shm)
{semctl(shm->semid, 0, IPC_RMID);return shmdt(shm->share);
}