在Python中使用Linux的IPC通信
在Python中使用Linux的IPC通信
说明
Linux下的IPC进程间通信包括有:消息队列,管道,共享内存,信号量,socket等。
在寻找信号量通信的使用库时,仅仅找到了multiprocessing
这个库,并没有发现能够直接和Linux C中的Semaphore直接通信的方法,于是自己动手封装了一遍库,使用python调用C动态库的方式实现。
如果有已经编写好的稳定的库,还请留言告知~。
目的
由于工作内容原因,需要实现两个进程间通信,并且一个进程是使用C编写的,另一个是Python编写,进程间的通信需要测试下使用共享内存的效率,已经实现的有C进程与C进程间的共享内存传输测试,为了保证操作的唯一性,必须使用信号量对共享内存中的数据进行保护,但是在使用Python实现时,发现没有找到可以和C进程信号量通信的方法,于是采用本办法,将C的信号量实现封装一层,再使用Python调用。
Semaphore C代码封装
源代码: linux_ipc_sem.c
/*
* linux_ipc_sem.c
*
* Created on: Dec 22, 2021
* Author: noven_zhang
*/
#include "linux_ipc_sem.h"
/**
* @brief 封装python使用的sem_open函数
* @param[in] *__name : 信号量名称
* @param[in] __oflag : 标志,具体参考man sem_open详细说明
* @param[in] mode : 模式,权限,具体参考man sem_open详细说明
* @param[in] value : 初始值,一般都为0, 具体参考man sem_open详细说明
* @return
* @retval NULL : 失败
* @retval not NULL: 成功,信号量flag存放地址
* @note 详细信息参考 man sem_open
*/
void* py_sem_open(const char *__name, int __oflag, unsigned int mode, unsigned int value)
{
sem_t* sem_flag = NULL;
sem_flag = sem_open(__name, __oflag, (mode_t)mode, value);
if (NULL == sem_flag)
{
fprintf(stderr, "failed to open semaphore: %s\n", __name);
return NULL;
}
return (void*)sem_flag;
}
/**
* @brief 封装python使用的sem_close函数
* @param[in] sem_flag : py_sem_open的返回值@see py_sem_open
* @return
* @retval -1 : 失败
* @retval 0 : 成功
* @note 详细信息参考 man sem_close
*/
int py_sem_close(void* sem_flag)
{
int ret_flag = -1;
ret_flag = sem_close((sem_t*)sem_flag);
return ret_flag;
}
/**
* @brief 封装python使用的sem_unlink函数
* @param[in] __name : 需要解绑的信号量的名称
* @return
* @retval -1 : 失败
* @retval 0 : 成功
* @note 详细信息参考 man sem_unlink
*/
int py_sem_unlink(const char *__name)
{
int ret_flag = -1;
ret_flag = sem_unlink(__name);
return ret_flag;
}
/**
* @brief 封装python使用的sem_wait函数
* @param[in] sem_flag : py_sem_open的返回值@see py_sem_open
* @return
* @retval 0 : 成功
* @retval 非0 : 失败
* @note 详细信息参考 man sem_wait
*/
int py_sem_wait(void* sem_flag)
{
int ret_flag = -1;
ret_flag = sem_wait((sem_t*)sem_flag);
return ret_flag;
}
/**
* @brief 封装python使用的sem_timedwait函数
* @param[in] sem_flag : py_sem_open的返回值@see py_sem_open
* @param[in] secs : 延时到的秒,从1970-01-01 00:00:00开始的秒
* @param[in] nsecs : 延时到的纳秒
* @returen
* @retval 0 : 成功
* @retval 非0 : 失败
* @note 详细信息参考 man sem_timedwait
*/
int py_sem_timedwait(void* sem_flag, long int secs, long int nsecs)
{
int ret_flag = -1;
struct timespec delay_time = {
0};
delay_time.tv_sec = secs;
delay_time.tv_nsec = nsecs;
ret_flag = sem_timedwait((sem_t*)sem_flag, &delay_time);
return ret_flag;
}
/**
* @brief 封装python使用的sem_trywait函数
* @param[in] sem_flag : py_sem_open的返回值@see py_sem_open
* @returen
* @retval 0 : 成功
* @retval 非0 : 失败
* @note 详细信息参考 man sem_trywait
*/
int py_sem_trywait(void* sem_flag)
{
int ret_flag = -1;
ret_flag = sem_trywait((sem_t*)sem_flag);
return ret_flag;
}
/**
* @brief 封装python使用的sem_post函数
* @param[in] sem_flag : py_sem_open的返回值@see py_sem_open
* @returen
* @retval 0 : 成功
* @retval 非0 : 失败
* @note 详细信息参考 man sem_post
*/
int py_sem_post(void* sem_flag)
{
int ret_flag =<