- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
msgsnd() 和 msgrcv() 在同一个函数中,它与第一个示例一样运行良好。
主.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pid_t pid1;
pid_t pid2;
pid_t pid3;
pid_t pid4;
if ((pid1 = fork()) < 0) {
printf("fork error\n");
} else if (pid1 == 0){
printf("I am in First process\n");
int nodeId = 1;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid2 = fork()) < 0) {
printf("fork error\n");
} else if (pid2 == 0){
printf("I am in second process\n");
int nodeId = 2;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid3 = fork()) < 0) {
printf("pid3 fork error\n");
} else if (pid3 == 0) {
printf("I am in Third process\n");
int nodeId = 3;
//cmc_init(nodeId);
test2(nodeId);
return 0;
}
if ((pid4 = fork()) < 0) {
printf("pid4 fork error\n");
} else if (pid4 == 0) {
printf("I am in Fourth process\n");
int nodeId = 4;
//cmc_init(nodeId);
//test2(nodeId);
return 0;
}
if (waitpid(-1, NULL, 0) < 0) {
printf("wait1 error\n");
}
sleep(3);
return 0;
}
comproc.c
typedef struct Msg_context {
int nodeId;
} Msg_context;
void test2(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1\n");
}
msgSend.nodeId = nodeId;
if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
printf("send message error\n");
}
}
//com_process_send(nodeId);
sleep(1);
while (1) {
//com_process_recv(nodeId);
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
}
运行良好,结果:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process
但是当我将 msgrcv() 放入另一个函数时,它无法正常工作。像这样:
comproc.c
typedef struct Msg_context {
int nodeId;
} Msg_context;
int com_process_recv(int nodeId)
{
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
void test2(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1\n");
}
msgSend.nodeId = nodeId;
if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
printf("send message error\n");
}
}
//com_process_send(nodeId);
sleep(1);
while (1) {
com_process_recv(nodeId);
}
}
结果是这样的:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 2, recv.nodeId = 3
[recv] nodeId = 1, recv.nodeId = 3
I am in Fourth process
或者像这样:
I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 3, ret = 4
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process
但是,但是,如果我也将 msgsnd() 放入另一个函数中,它会再次运行良好。
comproc.c
typedef struct Msg_context {
int nodeId;
} Msg_context;
int com_process_send(int nodeId)
{
int i = 1;
for (i = 1; i <= 3; i++) {
if (i == nodeId) {
continue;
}
int msgid = -1;
Msg_context msgSend;
msgid = msgget((key_t)i, 0666 | IPC_CREAT);
if (msgid == -1) {
printf("msgid == -1 in %s with nodeId = %d\n", __FUNCTION__, nodeId);
}
msgSend.nodeId = nodeId;
//int length = sizeof(msgSend.nodeId);
int ret = msgsnd(msgid, (void *)&msgSend, 4, 0);
if (ret == -1) {
printf("send message error in %s with nodeId = %d\n", __FUNCTION__, nodeId);
}
printf("[send] nodeId = %d, dest msg = %d\n", nodeId, i);
}
return 0;
}
int com_process_recv(int nodeId)
{
int msgrecvId = -1;
Msg_context msgRecv;
msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);
if (msgrecvId == -1) {
printf("msgrecvId == -1\n");
}
if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
printf("send message error\n");
}
printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);
}
void test2(int nodeId)
{
com_process_send(nodeId);
sleep(1);
while (1) {
com_process_recv(nodeId);
}
}
所以这很奇怪,对吧?我不明白为什么会这样。所以我非常希望你们能帮助我理解这一点。非常感谢!!!
最佳答案
根据我在您的评论中读到的内容,如果您希望不同的进程只读发送给它们的消息,您应该查看 msgrcv()
的 msgtyp
参数>
来自手册页:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
The argument msgtyp specifies the type of message requested as follows:
If msgtyp is 0, then the first message in the queue is read.
If msgtyp is greater than 0, then the first message in the queue of type msgtyp is read, unless MSG_EXCEPT was specified in msgflg, in which case the first message in the queue of type not equal to msgtyp will be read.
If msgtyp is less than 0, then the first message in the queue with the lowest type less than or equal to the absolute value of msgtyp will be read.
在你的例子中,调用
msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, nodeId) == -1)
将帮助您从第一个消息队列读取第一个进程,从第二个 msq 读取第二个进程,等等...
关于linux - 为什么 msgsnd() 和 msgrcv() 不能正常运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50636668/
我正在维护一些现有代码 我看到了这个片段: msgsnd( $mQueue, pack("l! a*", length($msg), $msg), 0)
我想在两个进程之间发送消息。但当我尝试使用 msgsnd() 发送消息时,出现 EACCES 错误 创建消息队列 const char* MSG_QUEUE = "/tmp/msg_queue"; i
使用以下代码: #define MSGLEN 128 typedef struct { long id; char message[MSGLEN]; } data; data msg; msgsnd(
[虽然我在 perl 工作,但我相信这个问题与 Linux System V IPC 有关API 和限制,而不是任何特定于 perl 的内容。] 我有两台 Centos 机器,每台机器都是 CentO
从信号处理程序调用 msgsnd 函数安全吗? 我们服务的代码并不打算每次都优雅地完成,所以我没有退出点,但是我需要在服务停止时向另一个进程发送消息,所以我需要捕获 SIGTERM 并执行 msgsn
当使用 msgsnd 时,手册页中提到的结构是 struct mymsg { long mtype; /* message type */ char mtext[1]; /
我有两个不同的程序: 第一个,基本上是无限循环地在消息队列上调用 msgrcv 并在它收到任何东西时打印,在 C++ 中: //foo1.cpp #include #include #includ
该进程创建了 n 个子进程(n 从标准输入读取),每个子进程必须每 2 秒向父进程发送一条消息,然后父进程将收到的每条消息发送给所有子进程。我正在使用 2 个消息队列:一个是所有子级向父级发送消息,另
如果两个线程“同时”调用 msgsnd() 函数,将消息发布到同一个消息队列,会发生什么情况? 如果两个进程做同样的事情怎么办?它们是线程还是进程重要吗? 特别关注 Linux 2.6.15-2.5
我正在尝试使用 pthreads 在 C 中实现一个多线程程序并想在线程之间发送消息。 在网上阅读时,我遇到了两种方法。 一种是 posix Queues,它使用诸如 mq_receive 之类的函数
我正在为考试学习操作系统基础知识,但遇到了一个奇怪的问题。我目前正在研究发送/接收功能。假设我有 3 个主程序 Client,它们通过 msgsnd() 原语发送消息。结构如下: typedef st
我正在编写一个使用 unix 消息队列的程序。问题是这样的,程序报告我“错误:22:无效参数”。我已经 brpwsed,但它不能满足我的搜索。这是简单的代码: bool msg::send(i
我有一个小的 C++ 程序,其中主进程正在“创建数据”并将它们发送到应该读取该数据的子(fork)进程。我的问题是,在学校我的代码运行良好,但在我自己的笔记本电脑上,两个进程在程序启动后立即卡住。具体
这件事困扰了我好几天。问题是我对 C 中的指针和地址不太了解,所以我希望有人能够帮助我。 我需要传递一些字符串作为输入参数,并创建尽可能多的生产者进程 + 一个消费者进程。 生产者应该将字符串分开并将
为了学习,我写了 2 个 IPC 程序,一个服务器和一个使用消息发送的客户端。由于某种原因,服务器似乎没有收到它已发送的数据。关于如何调试此类问题,您能给我一些提示吗? #include #incl
程序创建了两个子进程。第一个子进程 (1) 从 stdin 读取文本,删除任何特殊字符,然后拆分成单词。该程序的那部分工作得很好。然后,当 child (1) 拆分单词时,它通过消息队列发送每个完整的
msgsnd() 和 msgrcv() 在同一个函数中,它与第一个示例一样运行良好。 主.c #include #include #include int main(int argc, char
谁能帮我指出我程序中的错误是什么? 提前致谢,粉碎王1 #include #include #include #include #include #include #include ty
这是我的问题:我正在尝试在服务器和客户端之间实现消息队列。为此,我有两个文件,msq-server.c和 msq-client.c . 我使用函数 msgctl(msqid, IPC_RMID, &b
我编写了一个 C 程序来测试并行进程上的一些消息队列。消息定义如下: typedef struct _Message{ long type; int some_number;
我是一名优秀的程序员,十分优秀!