\documentclass[11pt]{beamer} %\usepackage{ngerman} \usepackage{times} \usepackage{graphicx} \usepackage{pgf,pgfarrows,pgfnodes,pgfautomata,pgfheaps} \usepackage{amsmath,amssymb} \usepackage[utf8]{inputenc} \usepackage{listings,color} \definecolor{lbcolor}{RGB}{255,210,150} \lstset{ language=C, numbers=left, stepnumber=1, numbersep=5pt, numberstyle=\tiny, breaklines=true, breakautoindent=true, postbreak=\space, tabsize=2, basicstyle=\ttfamily\fontsize{7}{9}\selectfont, showspaces=false, showstringspaces=false, extendedchars=true, backgroundcolor=\color{lbcolor}, keywordstyle=\bf , commentstyle=\color{green}, stringstyle=\color{red} } \mode { \usetheme{linutronix} } % on the following slides, include icon in the left sidebar \def\lximg{/usr/share/lx/icons/fueller.png} \title{POSIX IPC} \institute{Linutronix GmbH} \begin{document} \frame{ \titlepage } % stop displaying 'fueller.png' on the following slides \def\lximg{none} %\AtBeginSection[] %{ % \begin{frame} % \tableofcontents[currentsection,currentsubsection] % \end{frame} %} \AtBeginSubsection[] { \begin{frame} \tableofcontents[currentsection,currentsubsection] \end{frame} } \begin{frame} \tableofcontents \end{frame} \begin{frame} \frametitle{POSIX IPC: Übersicht} \begin{itemize} \item Message Queues \item Semaphores \item Shared Memory \end{itemize} \end{frame} \section{Message Queues} \begin{frame} \frametitle{POSIX Message Queues} \begin{itemize} \item Austausch von Daten in Form von Messages \item Messages sind priorisierbar \item Höchste Priorität wird zuerst ausgeliefert \item Virtuelles Filesystem unter /dev/mqueue \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: API} Message Queue öffnen / neu anlegen: \begin{lstlisting} #include #include #include mqd_t mq_open(const char *name, int oflag); mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: API} Message Queue schliessen: \begin{lstlisting} #include mqd_t mq_close(mqd_t mqdes); \end{lstlisting} Message Queue löschen: \begin{lstlisting} #include mqd_t mq_unlink(const char *name); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: API} Messages senden: \begin{lstlisting} #include mqd_t mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); #define _XOPEN_SOURCE 600 #include #include mqd_t mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: API} Messages empfangen: \begin{lstlisting} #include ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); #define _XOPEN_SOURCE 600 #include #include ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: Beispiel} Sender: \begin{lstlisting} const char message[] = "Hallo\0"; mqd_t ret; mqd_t mq = mq_open ("/my_queue", O_RDWR | O_CREAT | O_EXCL, 0664, NULL); if (mq < 0) { perror("Can't open message queue\n"); exit(1); } ret = mq_send(mq, message, sizeof(message), 100); if(ret < 0) perror("Can't send message\n"); mq_close(mq); return 0; \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{POSIX Message Queues: Beispiel} Empfänger: \begin{lstlisting} char message[8192]; unsigned prio; mqd_t ret; mqd_t mq = mq_open ("/my_queue", O_RDONLY); if(mq < 0) { perror("Can't open message queue\n"); exit(1); } ret = mq_receive(mq, message, 8192, &prio); if (ret < 0) perror("Nothing to receive\n"); else printf("Received message %s with prio %u\n", message, prio); mq_close(mq); mq_unlink("/my_queue"); return 0; \end{lstlisting} \end{frame} \section{Semaphoren} \begin{frame} \frametitle{POSIX Semaphoren: Übersicht} \begin{itemize} \item Synchronisation von Threads und Prozessen \item Named Semaphores \item Unnamed Semaphores (memory based) \item Virtuelles Filesystem unter /dev/shm \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Named Semaphores: API} Semaphore öffnen / neu erstellen: \begin{lstlisting} #include #include #include sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Named Semaphores: API} Unlock auf Semaphore: \begin{lstlisting} #include int sem_post(sem_t *sem); \end{lstlisting} Lock auf Semaphore: \begin{lstlisting} #include int sem_wait(sem_t *sem); int sem_trywait(sem_t *sem); int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Named Semaphores: API} Semaphore schliessen: \begin{lstlisting} #include int sem_close(sem_t *sem); \end{lstlisting} Semaphore löschen: \begin{lstlisting} #include int sem_unlink(const char *name); \end{lstlisting} \end{frame} \begin{frame} \frametitle{Unnamed Semaphores: Übersicht} \begin{itemize} \item Liegen in einem gemeinsamen Speicherbereich (z.B. Shared Memory) \item Müssen mit sem\_init() initialisiert werden \item Lock und Unlock mit sem\_post() und sem\_wait() \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Unnamed Semaphores: API} Initialisieren: \begin{lstlisting} #include int sem_init(sem_t *sem, int pshared, unsigned int value); \end{lstlisting} Zerstören: \begin{lstlisting} #include int sem_destroy(sem_t *sem); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Semaphoren: Beispiel} \begin{lstlisting} sem_t *my_sem; int ret; my_sem = sem_open("/my_sem", O_RDWR | O_CREAT | O_EXCL, 0644, 0); if (my_sem == SEM_FAILED) { perror("Can't open semaphore\n"); exit(1); } ret = sem_wait(my_sem); if(ret < 0) { perror("sem_wait failed\n"); exit(1); } printf("Here I am :)\n"); sem_close(my_sem); return 0; \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Semaphoren: Beispiel} \begin{lstlisting} sem_t *my_sem; int ret; my_sem = sem_open("/my_sem", O_RDWR); if(my_sem == SEM_FAILED) { perror("Can't open semaphore\n"); exit(1); } ret = sem_post(my_sem); if (ret < 0) perror("sem_post\n"); sem_close(my_sem); return 0; \end{lstlisting} \end{frame} \section{Shared Memory} \begin{frame} \frametitle{Shared Memory: Übersicht} \begin{itemize} \item Gemeinsam genutzter Speicherbereich \item mmap() \item Virtuelles Filesystem unter /dev/shm \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Shared Memory: API} Shared Memory anlegen / zerstören \begin{lstlisting} #include #include #include int shm_open(const char *name, int oflag, mode_t mode); int shm_unlink(const char *name); \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Shared Memory: Beispiel} \begin{lstlisting} int fd; int ret = 1; char *addr; fd = shm_open("my_shm", O_RDWR | O_CREAT, 0777); if (fd < 0) { perror("Can't open Shared Memory\n"); goto out; } if (ftruncate(fd, 4096) == -1) { perror("ltrunc\n"); goto out; } addr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { perror("mmap() failed\n"); goto out; } ret = 0; *addr = 'A'; out: close(fd); return ret; \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Shared Memory: Beispiel} \begin{lstlisting} int fd; int ret = 1; char *addr; fd = shm_open("my_shm", O_RDWR, 0777); if (fd < 0) { perror("Can't open Shared Memory\n"); goto out; } addr = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { perror("mmap() failed\n"); goto out; } printf("Reading from SHM -> %c\n", *addr); ret = 0; out: close(fd); return ret; \end{lstlisting} \end{frame} \end{document}