进程间通信

james_hw 2010-05-26 06:55:46
如果我设计一个日志进程,供其他进程(同一个cpu)写日志。以下是我不懂得地方。

1、想使用共享内存,这样可以多个进程间共享,在linux下,如何做到多个进程共享一块内存(我看了下《unix高级环境编程》,里面举的例子不是很明白,例如shmget一块内存出来,如何让其他进程共享呢?)
2、当多个进程写日志时,自然要做到同步操作,在linux下,多个进程之间如何共享锁(windows下我记得可以共享内核对象达到共享锁的目的)。

...全文
320 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanran_hill 2010-05-28
  • 打赏
  • 举报
回复
一对多?那使用消息队列怎么样?同样能保证数据的原子操作,而且没有数据长度的限制
DemonWhisper 2010-05-27
  • 打赏
  • 举报
回复
多个进程同时操作一块共享内存,需要排队/分区,逻辑复杂度你自己比划过没?
赵4老师 2010-05-27
  • 打赏
  • 举报
回复
写日志最主要还是内容详尽、便于查找;至于效率可以不用太高。
yanran_hill 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 jamesf1982 的回复:]
引用 19 楼 yanran_hill 的回复:
楼主可以使用命名管道来接收其它进程的写日志的数据,只要长度不超过计划256字节,而且管道缓冲区有足够的剩余空间的话,那么就可以保证写到管道的数据是原子的不可分割的,这样实现起来也很简单
管道也是IPC通信的一种,而且对管道的操作,也和操作内存一样的"快"


管道麻烦的地方呢,一是日志进程要和所有进程建立管道,二是日志进程不负责fork其……
[/Quote]
可以使用命名管道,不麻烦,只需要先mknod创建管道文件,然后在C++中象普通文件一样打开,就可以了,日志进程以读方式打开,读出数据转存到文件,其它进程以写方式打开,写入数据就行了
james_hw 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yanran_hill 的回复:]
楼主可以使用命名管道来接收其它进程的写日志的数据,只要长度不超过计划256字节,而且管道缓冲区有足够的剩余空间的话,那么就可以保证写到管道的数据是原子的不可分割的,这样实现起来也很简单
管道也是IPC通信的一种,而且对管道的操作,也和操作内存一样的"快"
[/Quote]

管道麻烦的地方呢,一是日志进程要和所有进程建立管道,二是日志进程不负责fork其他进程,而其他进程的启动顺序未知,三是日志进程就算建立管道,如何将管道共享给其他进程呢?

yanran_hill 2010-05-27
  • 打赏
  • 举报
回复
楼主可以使用命名管道来接收其它进程的写日志的数据,只要长度不超过计划256字节,而且管道缓冲区有足够的剩余空间的话,那么就可以保证写到管道的数据是原子的不可分割的,这样实现起来也很简单
管道也是IPC通信的一种,而且对管道的操作,也和操作内存一样的"快"
howema 2010-05-27
  • 打赏
  • 举报
回复
创建共享内存
添加共享内存到操作进程地址空间
操作
释放共享内存
Cniao_zhi 2010-05-27
  • 打赏
  • 举报
回复
是这样的,由日志进程维护该文件,而其他进程要写日志呢?

LZ是要写文件呢还是要写共享内存里呢?没懂。。。。
james_hw 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yanran_hill 的回复:]
1.如果我设计一个日志进程,供其他进程(同一个cpu)写日志。以下是我不懂得地方。

写日志的基本思路,是提供一种服务,把其它进程提交的日志信息,保存到文本或者数据库中去,这里有一点疑问:写日志应该是写数据到文件或者数据库,和共享内存有什么关系呢?
在UNIX系统下,有关于日志服务的详细地例子,楼主不妨借鉴一下。

2.进程间的锁,目前比较常用的是:
a.System V下的信号灯(s……
[/Quote]

是这样的,由日志进程维护该文件,而其他进程要写日志呢,先通过接口把消息发送给日志进程(由于进程不只是两个,因此不想用管道,最好用共享内存)。正如你所说的数据库,不过我们的flash不够大,无法放下一个数据库,要做好自己维护。至于日志服务的例子,我在百度上还没找到,能方便指示一下么?
Cniao_zhi 2010-05-27
  • 打赏
  • 举报
回复
shmid不是传的 是其他进程也做同一操作得来的
Cniao_zhi 2010-05-27
  • 打赏
  • 举报
回复
新建
ftok() //新建共享内存的时候是IPC_CREAT|权限
shmget()
shmat()

其他进程使用时
ftok() //不填写IPC_CREAT 只填写权限
shmget()
shmat()

通过ftok函数可以获取一个KEY shmget函数是通过这个KEY值获取一个shmid shmat函数通过shmid返回共享内存的基地址 这个时候就可以用啦
至于同步的问题 就是用信号量来解决 基本原理都差不多
key
james_hw 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 thehunters 的回复:]
创建:shmid = shmget(key, sizeof(MSGQ_HEADER), IPC_EXCL|flags);
连接:char*ptr = (char*)shmat(shmid, NULL, 0);
更改:strcpy(ptr,"a");
[/Quote]

shmid如何传递给其他进程?
thehunters 2010-05-27
  • 打赏
  • 举报
回复
创建:shmid = shmget(key, sizeof(MSGQ_HEADER), IPC_EXCL|flags);
连接:char*ptr = (char*)shmat(shmid, NULL, 0);
更改:strcpy(ptr,"a");
DemonWhisper 2010-05-27
  • 打赏
  • 举报
回复
你自己用 sysv shm / sem 实现的效率真的能比 FIFO 高很多么?测过没有?
因为实际上实现一个基于 shm 的 ring buffer 还是相当多麻烦的。
yanran_hill 2010-05-27
  • 打赏
  • 举报
回复
1.如果我设计一个日志进程,供其他进程(同一个cpu)写日志。以下是我不懂得地方。

写日志的基本思路,是提供一种服务,把其它进程提交的日志信息,保存到文本或者数据库中去,这里有一点疑问:写日志应该是写数据到文件或者数据库,和共享内存有什么关系呢?
在UNIX系统下,有关于日志服务的详细地例子,楼主不妨借鉴一下。

2.进程间的锁,目前比较常用的是:
a.System V下的信号灯(semget...)
b.POSIX 标准的信号量(sem_init...)

由于历史的原因,目前在System V下的信号灯使用的很多,尤其是在多进程之间存取同一块共享内存的场合

james_hw 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 huzhibin2000 的回复:]
一般通过文件名字来共享一块内存的。
key_t ftok(const char *pathname, int proj_id);

ftok函数可以通过传入文件全路径做参数,得到一个key,然后可以用这个key创建共享内存,同样其他进程也能通过路径得到key,再得到共享内存。
[/Quote]

呵呵,多谢,不过pathname,这个文件必须存在,它是如何创建的?另外对这块内存操作时如何让多进程同步呢?
cattycat 2010-05-27
  • 打赏
  • 举报
回复
本地的话,你用共享内存比较快。具体用法百度吧。上面那个链接不太详细。
即使fork还是要在父子进程间同步的。我这里没有unix环境高级编程,看来还得深入看看了。
友情帮你up。
cattycat 2010-05-27
  • 打赏
  • 举报
回复
linux进程通信方式很多,共享内存,管道,信号,消息队列等。
看看这个吧。
http://www.ibm.com/developerworks/cn/linux/l-ipc/
james_hw 2010-05-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 skyworth98 的回复:]
fork一个新线程出来就好了
linux下的线程无非是共享资源的进程而已
[/Quote]

1、一定得由日志进程fork出来么,事实上有可能是调度进程将日志进程等多个进程fork来,因此有可能是调度进程划分出一块物理内存,然后包括日志进程在内的所有进程共享这块内存。如何划分?如何共享?
2、线程间可以随意共享进程内的资源,但是进程间的地址是无法互相共享的,因此必须将某块划分好的物理内存映射到自己进程的逻辑地址空间。但是进程如何知道这块物理内存?如何映射?
3、对同一内存的访问,必须用锁,但是锁如何在进程间共享?
huzhibin2000 2010-05-27
  • 打赏
  • 举报
回复
int shmget(key_t key, size_t size, int shmflg);
补充:看到了没有,shmget的第一个参数是key_t的,这个需要先通过ftok得到。因此文件名就是共享内存的唯一标记了。
加载更多回复(7)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧