I used the following two little programs:
============ unixdomain.c ==============
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
int
main (void)
{
struct sockaddr_un address;
int socket_fd, nbytes;
char buffer[256];
socket_fd = socket (PF_UNIX, SOCK_DGRAM, 0);
if (socket_fd < 0)
{
printf (“socket() failed\n”);
return 1;
}
/* start with a clean address structure */
memset (&address, 0, sizeof (struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf (address.sun_path, FILENAME_MAX, “./demo_socket”);
if (connect (socket_fd,
(struct sockaddr *) &address,
sizeof (struct sockaddr_un)) != 0)
{
printf (“connect() failed\n”);
return 1;
}
while (1)
{
struct timeval tv;
gettimeofday (&tv, NULL);
write (socket_fd, &tv, sizeof (tv));
usleep (100000);
}
return 0;
}
===== unixdomain_server.c ========
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
int
main (int argc, char **argv)
{
struct sockaddr_un address;
int socket_fd;
socklen_t address_length;
unsigned char buffer[512];
struct timeval now, msg;
int cnt = 0;
long long diff = 0LL;
socket_fd = socket (PF_UNIX, SOCK_DGRAM, 0);
if (socket_fd < 0)
{
printf (“socket() failed\n”);
return 1;
}
/* start with a clean address structure */
memset (&address, 0, sizeof (struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf (address.sun_path, FILENAME_MAX, “./demo_socket”);
unlink (address.sun_path);
if (bind (socket_fd,
(struct sockaddr *) &address, sizeof (struct sockaddr_un)) != 0)
{
perror (“bind() failed”);
return 1;
}
while (read (socket_fd, &msg, sizeof (msg)) >= sizeof (msg))
{
long long t1, t2;
t1 = msg.tv_sec * 1000000;
t1 += msg.tv_usec;
gettimeofday (&now, NULL);
t2 = now.tv_sec * 1000000;
t2 += now.tv_usec;
diff += (t2 - t1);
cnt++;
if ((cnt % atoi (argv[1])) == 0)
{
fprintf (stderr, "%f\n", (double) diff / (double) atoi (argv[1]));
diff = 0LL;
}
}
close (socket_fd);
unlink (“./demo_socket”);
return 0;
}
And found no significant difference in peak and average latencies
between them.
The unixdomain_server takes a single command-line argument which tells
it how many samples
to average over before producing a printed result.
So this confirms my earlier assertion that I would be surprised to find
a significant latency difference
between Unix-domain sockets and FIFOs, since the interior kernel
mechanisms are broadly similar.
Basically–some chunk of memory is copied from one place to another,
there’s some housekeeping, and
the system-call interface is traversed a couple of times.
–
Principal Investigator
Shirleys Bay Radio Astronomy Consortium