If I have a message queue
mqd_t m;
m = mq_open(NAME,O_CREAT | O_RDWR, 0666, NULL);
Is it possible to send a message on it and the same process to perform a receive on the
same message ?
Thank you!
Why not? It could. See the official mannual here: http://man7.org/linux/man-pages/man3/mq_open.3.html
The argument O_RDWR means:
O_RDWR Open the queue to both send and receive messages.
Like a file object, you could read and write it in one process.
Related
if((nbytes=mq_receive (qid_recv, (pchar_t)in_buffer, msg_buffer_size, NULL)) != -1) {
printf("nbytes is %ld\n", nbytes);
}else{
perror("recv_data");
printf("nbytes is %ld\n", nbytes);
How to exit from the mq_receive if there is no message is received.Is there any possiblity for give a timeout.Thanks for your time.
In addition to mq_timedreceive(), you can also set the O_NONBLOCK when you open the queue with mq_open(). Per the mq_open() documentation:
O_NONBLOCK
Determines whether an mq_send() or mq_receive() waits for resources or messages that are not currently available, or fails with errno set to EAGAIN; see mq_send and mq_receive for details.
Per the mq_receive() documentation:
If the specified message queue is empty and O_NONBLOCK is set in the message queue description associated with mqdes, no message shall be removed from the queue, and mq_receive() shall return an error.
You can use mq_timedreceive function.
See i know there are various methods to communicate between threads but my question is specific for LINX. Please answer.
Thanks in advance
threads of the same process share heap staff, synchronized by thread lock, Semaphore and condition variable.
Besides, The communication approach from Interprocess communication(IPC for example, PIPE/FIFO/MessageQueue/SharedMemory/Signal/Socket) works for threads communication, too. take FIFO for example(neglect error code checking):
char buf[110];
char *FIFO = "/tmp/my_fifo";
mkfifo(FIFO, O_CREAT);
int fd = open(FIFO, O_RDONLY, 0);
int nread = read(fd, buf, 100);
Well as per #lulyon, this method can also be implemented. Well for LINX specific, interthread is possible.
LINX_SEND(endpoint, signal, SPID of dest). My bad i was sending dest Endpoint instead of SPID
I have a really annoying problem while trying to read from multiple fifos. I have 1 process that waits for structure from fifo and few processes that are sending him those structures on signal. After first read I can't read anything more.. from any signal. It looks like the program frozes.
The sending process has this in main with
myfifo = '/tmp/myfifo{0}' //{0} is a number that every process has individual.
mkfifo(myfifo, 0666);
fd = open(myfifo, O_WRONLY);
write(fd, &demon1 , sizeof(demon1));
close(fd);
while (1)
{
}
and this in signal_handler
void signal_handler(int signum)
{
if (signum == SIGUSR1)
{
//some declarations here
mkfifo(myfifo, 0666);
fd = open(myfifo, O_WRONLY | O_NONBLOCK);
write(fd, &demon1 , sizeof(demon1));
}
}
While the reading process has
myfifo[i] = /tmp/myfifo{0} // {0} is i which is the number of process that sends.
while(1)
{
for(i=0;i<n;i++)
{
fd = open(myfifo[i], O_RDONLY | O_NONBLOCK);
r = read(fd, &demon1, sizeof(demon1));
if(r > 1)
{
//printf struct elements
}
}
}
You open the pipe inside the loop. That way, you quickly run out of file descriptors (which you would see if you checked the result of open() for errors).
I suggest to open all FIFOs outside the loop, store the file descriptors in an array and then just read each of them but ... the read will block. See select(2) to find out which FIFO has data.
Another solution would be a single FIFO and the writing process should send it's ID in the message. That way, the main process just has to listen to a single FIFO. If it wants to know who sent the message, it can look at the ID in the message. The problem here: You need some kind of locking or several processes will write to the FIFO at the same time and their data can get mixed up (this depends on the FIFO buffers).
You do not close the filedescriptors after opening and reading:
while(1)
{
for(i=0;i<n;i++)
{
fd = open(myfifo[i], O_RDONLY | O_NONBLOCK);
r = read(fd, &demon1, sizeof(demon1));
if(r > 1)
{
//printf struct elements
}
Here a close(fd) is missing.
}
}
Since the open is non-blocking, the maximum number of fds per process is reached very soon and subsequent opens will fail.
I m developing a C application running on linux system (kernel 3.4.11)
In my application, I m opening a server socket on a thread. And I m opening a fork() in which I execute a shell command with execvp() in the main thread.
Opening a fork() will inherit the socket file descriptor in the child. And this could cause problems according to many topics on the net. In my case If I close my application I can see with netstat that the socket is assigned to another daemon (another random daemon).
In fact there is many solutions for a such issue:
1) close the socket on the beginning of the fork() child:
if ((pid = fork()) == -1)
return -1;
if (pid == 0) {
/* child */
close(socket_desc);
2) Use fcntl() and FD_CLOEXEC when opening the socket in the parent
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
fcntl(socket_desc, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
3) Use O_CLOEXEC in the socket() function:
socket_desc = socket(AF_INET , SOCK_STREAM|O_CLOEXEC , 0);
What's the best solution? and why?
Any other better solution is welcome.
If you control all the code, these make no difference.
Use the first solution if someone else gives you a socket you don't know how it was created.
Use the second, if you write a module to which someone else transmit you a socket, and you want to pass it to another module you don't control but you suspect to fork()/exec().
Use the third if you are the creator of the socket and need to pass it to another module that you suspect to fork()/exec().
I am trying to make a simple client-server chat program. On the client side I spin off another thread to read any incomming data from the server. The problem is, I want to gracefully terminate that second thread when a person logs out from the main thread. I was trying to use a shared variable 'running' to terminate, problem is, the socket read() command is a blocking command, so if I do while(running == 1), the server has to send something before the read returns and the while condition can be checked again. I am looking for a method (with common unix sockets only) to do a non-blocking read, basically some form of peek() would work, for I can continually check the loop to see if I'm done.
The reading thread loop is below, right now it does not have any mutex's for the shared variables, but I plan to add that later don't worry! ;)
void *serverlisten(void *vargp)
{
while(running == 1)
{
read(socket, readbuffer, sizeof(readbuffer));
printf("CLIENT RECIEVED: %s\n", readbuffer);
}
pthread_exit(NULL);
}
You can make socket not blockable, as suggested in another post plus use select to wait input with timeout, like this:
fd_set input;
FD_ZERO(&input);
FD_SET(sd, &input);
struct timeval timeout;
timeout.tv_sec = sec;
timeout.tv_usec = msec * 1000;
int n = select(sd + 1, &input, NULL, NULL, &timeout);
if (n == -1) {
//something wrong
} else if (n == 0)
continue;//timeout
if (!FD_ISSET(sd, &input))
;//again something wrong
//here we can call not blockable read
fcntl(socket, F_SETFL, O_NONBLOCK);
or, if you have other flags:
int x;
x=fcntl(socket ,F_GETFL, 0);
fcntl(socket, F_SETFL, x | O_NONBLOCK);
then check the return value of read to see whether there was data available.
note: a bit of googling will yield you lots of full examples.
You can also use blocking sockets, and "peek" with select with a timeout. It seems more appropriate here so you don't do busy wait.
The best thing is likely to get rid of the extra thread and use select() or poll() to handle everything in one thread.
If you want to keep the thread, one thing you can do is call shutdown() on the socket with SHUT_RDWR, which will shut down the connection, wake up all threads blocked on it but keep the file descriptor valid. After you have joined the reader thread, you can then close the socket. Note that this only works on sockets, not on other types of file descriptor.
Look for function setsockopt with option SO_RCVTIMEO.