This is probably a really dumb question, but googling isn't working out so here goes. I am writing a program using message queues to send a range of values to different processes. I have done research that indicates that I use msgsnd() to store a message on the queue and msgrcv() to receive messages. I need to store a start number and an end number in the queue. So my question is can I store multiple messages in this queue and if so, how to I go about storing them and retrieving them? TIA for all your help.
The concept of a queue means you can put things in (msgsnd) which creates one message in the queue. To receive one message, you have to call msgrcv. Each receive will normally only return one message, so if you send n messages, you have to receive n messages.
Queues are generally seen as FIFO (first in, first out), so the message creates by the first msgsnd will be the first message returned by msgrcv.
This is a little weakend if you message queues that operate over the network (and/or in a cluster). Due to network latency/failover/retries etc messages can get out of order, so it's generally advised to build the messages with all necessary information in them to process correctly for those cases.
Related
I am creating a C application, which will be executed in openwrt router device. Because of limited resources I'm a bit scared about the message queue. What if the "reader" application, which takes the messages from the queue, crash and the "writer" still sends the messages? Should I be worried about the device's memory or will the message queue clean itself eventually?
EDIT I realised that I wasn't clear enough about my task. One application will be sending messages and other will be reading and processing them.
See the documentation for msgsnd:
The queue capacity is governed by the msg_qbytes field in the associated data structure for the message queue. During queue creation this field is initialized to MSGMNB bytes, but this limit can be modified using msgctl(2).
If insufficient space is available in the queue, then the default behavior of msgsnd() is to block until space becomes available. If IPC_NOWAIT is specified in msgflg, then the call instead fails with the error EAGAIN.
So the sender will wait for the receiver to process a message, unless you use IPC_NOWAIT, in which case it returns EAGAIN and the sender can check for this error code.
The default maximum buffer size is specified in a constant called MSGMNB. You can print this value to see what it is on your system. To change the maximum size for your queue, you can use the function msgctl.
I have tried calling kill from process A to process B and the process B has successful reacted to the signal. The problem is I don't want to send signals from the kill function directly for two reasons:
1) Sometimes the process A may not have the permissions, ex. process B is ran by another user
2) I want to be able to send signals from A to B through the message queue
I am creating a message queue from which I send "objects" of the following structure
typedef struct msg {
long message_type;
char message_text[SIZE];
}message;
I want to know if it is possible for process A to signal B through IPC Message Passing. I know I can achieve this by sending the signal type into the message_text from process A to B and then inside the process B check the type of the signal and act properly but I was wondering if there is another way.
Would this be possible by passing sigaction objects as messages:
struct sigaction as;
//...
msgsnd(queue_id, &as, length, IPC_NOWAIT);
//...
I know this is completely infeasible but this is what I am trying to achieve. Thank you
Based upon your comments it seems that you want B to be able to receive messages but when it receives a "signal" message it needs to act like it received a regular signal. You mentioned that the B needed to react to SIGTERM or SIGINT from the "signal" message.
The way to achieve this is depends upon using POSIX message queues or System V message queues.
Either way it doesn't seem that you want to use polling of the message queue by the main thread of B as that would add to much latency to responding to the "signal" message.
So with POSIX message queues you can use mq_notify() to run either a thread or raise a signal that a new message has arrived. Otherwise B can use a thread (or even fork()) to poll the message queue.
After a "signal" message is received you have a couple of options. A) You can use either kill or raise in B to send a signal of the correct type to itself (or parent in case of fork), or B) just call a function that does what you want (that sort of thing).
Process A can send a "signal" message whenever it wants. But you need to understand that if you are using named queues they are persistent. That is that A can send a "signal" message before B even starts, and then when B starts that message is waiting there. Depending on how the message queue is made it can be N messages deep and have older messages in the queue. One way to deal with that is for B to empty the queue before processing any of the messages.
Message queues can’t achieve how signals do. With signal it is possible to asynchronously interrupt or kill process but with message queue when receiving process checks message or wait on it and exits after receiving message, it actually will ignore that message rest of path of execution(synchronous). But, It is possible to achieve with threads.
If you were using a POSIX message queues (using mq_send/mq_receive), then process B can request (with mq_notify) to be sent a signal every time a message is sent to the message queue. However, your example seems to be using a SYSV legacy message queue (msgsnd) which does not suppport any kind of notify.
thank you for reading. I'm currently implementing both the server and client for a socket server in C using linux. Currently i have a working "chat" system where both the server and the socket can send unique messages and the other end would receive that message with the correct length.
example output:
Server side
You:Hello!
client:hi, how are you?
You: fine thanks.
client: blabla
..And the client side would look be as follows:
server: Hello!
you:hi,how are you?
etc etc.
My question is, is there any way for the client/server to be able to send multiple messages before the other replies?
I currently have an endless while loop that waits for a receive and then proceeds to send, and this will repeat until the connection is lost. Using this method i can only send one message before i am forced to wait for a receive. I'm not sure of the correct implementation as I'm still quite new to both sockets and C! Thanks :)
Yes it could be possible.
The main body of your code, does not wait on socket for data. It reads the socket if data is already on it. It is possinle by using select function. After the select call, it reads the socket to display the received messages and sends user messages to other peer if there are ready on input.
A generic solution: You must use threading, and i'd propose to run the receiving part in a separate thread.
Hence, you first code the main thread to only manage sending, just as if the application couldn't receive at all. Apparently you have an edit field somewhere (and a messgae loop somehow). Each time the user presses Enter, you Send from within the Edit field's callback function.
Then you code a separate thread, that calls (and hangs on, blocks on) Receive(). Each time Receive "slips on" (ie. data came in), you do something with the data and then jump back to the Receive entry point. This goes on until you terminate the socket, or by other means decide to in fact not jump back to the Receive entry point.
The only situation where the two threads "touch" each other is when they both want to write text content to the same chat window. Both shall do it immediately as the transmission happens, but potentially both may try to access the chat window at exactly the same moment, causing a crash. Hence you muct apply a locking mechanism here; the one that first tries to access the chat window "gets it", while the locking mechanism keeps the other one on hold until the first releases the lock. Then the second one can do it's job. The locking is after all only a matter of microseconds.
These are immediate actions, free from each other. You don't need to que multiple messages; each one gets processed "as it happens".
I am programming with pthread in C language. I want a thread to tell other threads that it has put a message on the message queue, so that other threads would know that they can fetch messages from the message queue. However, the thread which has sent the signal should supply more information to other threads, such as thread id, message tag, and so on. How to do that ?
I know pthread_kill function, but It seems take little information. Can I take more information when I use a thread send signal to other threads ?
A signal in the C sense is not able to take "more information" - if you want to send more information, then you need to include that as part of the message in the message_queue, rather than as part of the signal.
I'm pretty sure there are dozens of alternatives. Just that you haven't thought of them. Like I said, if you want to use signals, then use a signal to indicate that there is a message (like the telephone ringing) then use a message queue to convey the actual information (talking on the phone). We don't use the phone ring signal to convey the message over the phone, right?
But I fear that you have somehow misunderstood the usage of threads and signals. I'm pretty sure that the way you are SUPPOSED to solve whatever you ar doing, isn't the right way.
Since your question is "How do I send more than an integer in a signal, I think you should accept Arno's answer, and then try again if that doesn't help - with a description of what your OVERALL problem is that you are trying to solve - right now you are talking to a mechanic about how to losen a bolt, but what you really need to do is fix a puncture, so you may be too concentrated on how to solve the detail, to muss the fact that you haven't even got a jack to lift the car off the ground...
Threads of a process share the same adress space. Thus it is common to build a mutex protected message queue for interthread communication. See this answer to get into the details. The message queue may be a custom design e.g. a linked list structure which may contain elements like sender ThreadID, receiver ThreadID, the message, and optional any number of additional parameters like message state or something. It may also contain a unique message ID and a parameter to tell the receiving thread how to proceed, e.g. remove the message from the queue or not.
A signal can still be used to avoid polling the message queue for new messages. A signal will trigger threads to read the mutex protected message queue for new messages. Another way is to build up an event scheme, as described in this answer. But this is in fact also a mutex protected global identifier which is set and the waiting thread is polling for the change (so called busy wait). Could do the busy wait on the mutex protected message queue right away. See this link for more information about pthread_cond_wait.
This is for an assignment I'm working on, and NO I'm not looking for you to just GIVE me the answer. I just need someone to point me in the right direction, maybe with a line or two of sample code.
I need to figure out how to set the priority of a file read operation from within my program. To the point:
server process receives a message and spawns a child to handle it
child tries to open the filename from the message and starts loading the file contents into the message queue
there may be several children running at the same time, and the initial message contains a priority so some messages may get more device access
The only way I can think to do this (right now, anyways) would be to increment a counter every time I create a message, and to do something like sched_yield after the counter reaches a given value for that process' assigned priority. That's most likely a horrible, horrible approach, but it's all I can think of at the moment. The assignment is more about the message queues than anything else, but we still have to have data transfer priority.
Any help/guidance is appreciated :)
Have the pool of child processes share a semaphore. Once a child acquires the semaphore it can read a predefined number of bytes from the resource and return it to the client. The number of bytes read can be related to the priority of the request. Once the process has read the predefined number of bytes release the semaphore.
Until recently, there was no IO prioritization in Linux. Now there is ionice. But I doubt you are meant to use it in your assignment.
Are you sure your assignment is talking about files and not system V message queues?
Read the man pages for:
msgctl(2), msgget(2), msgrcv(2), msgsnd(2), capabilities(7),
mq_overview(7), svipc(7)
Although I think you can use a file as a key to create a message queue, so that multiple processes have a way to rendezvous via the message queue, a Sys V message queue itself is not a file.
Just wondering because you mention "message queues" specifically, and talk about "priorities", which might conceivably map to the msgtyp field of eg. msgsnd and msgrcv, though it's hard to tell with what information you've given what the assignment really is about.