Linux API/linux2022. 9. 20. 14:43

ZMQ 혹은 0MQ 라고도 쓰는것 같은데 접속 모델부터 좀 찾아 보는 중

 

REQ-REP는 단순(?)한 요청-응답 모델이고

PUB-SUB는 서버에 의한 broadcast 모델 pipeline은 아직 모르겠다.

REQuest-REPly
PUBlisher - SUBscriber
PUSH- PULL (pipeline)

[링크 : https://soooprmx.com/zmq의-기본-개념들/]

[링크 : https://makersweb.net/opensource/19422]

[링크 : https://zeromq.org/]

 

Figure 2 - Request-Reply Figure 4 - Publish-Subscribe Figure 5 - Parallel Pipeline
Figure 6 - Fair Queuing    
   

[링크 : https://zguide.zeromq.org/docs/chapter1/]

 

Shared Queue (DEALER and ROUTER sockets)
In the Hello World client/server application, we have one client that talks to one service. However, in real cases we usually need to allow multiple services as well as multiple clients. This lets us scale up the power of the service (many threads or processes or nodes rather than just one). The only constraint is that services must be stateless, all state being in the request or in some shared storage such as a database.

[링크 : https://zguide.zeromq.org/docs/chapter2/]

 

Request-Reply Combinations
We have four request-reply sockets, each with a certain behavior. We’ve seen how they connect in simple and extended request-reply patterns. But these sockets are building blocks that you can use to solve many problems.

These are the legal combinations:

REQ to REP
DEALER to REP
REQ to ROUTER
DEALER to ROUTER
DEALER to DEALER
ROUTER to ROUTER

[링크 : https://zguide.zeromq.org/docs/chapter3/]

 

Messaging Patterns

Underneath the brown paper wrapping of ZeroMQ’s socket API lies the world of messaging patterns. ZeroMQ patterns are implemented by pairs of sockets with matching types.
The built-in core ZeroMQ patterns are:
  • Request-reply, which connects a set of clients to a set of services. This is a remote procedure call and task distribution pattern.
  • Pub-sub, which connects a set of publishers to a set of subscribers. This is a data distribution pattern.
  • Pipeline, which connects nodes in a fan-out/fan-in pattern that can have multiple steps and loops. This is a parallel task distribution and collection pattern.
  • Exclusive pair, which connects two sockets exclusively. This is a pattern for connecting two threads in a process, not to be confused with “normal” pairs of sockets.
XPUB socket
Same as PUB except that you can receive subscriptions from the peers in form of incoming messages. Subscription message is a byte 1 (for subscriptions) or byte 0 (for unsubscriptions) followed by the subscription body. Messages without a sub/unsub prefix are also received, but have no effect on subscription status.
XSUB socket
Same as SUB except that you subscribe by sending subscription messages to the socket. Subscription message is a byte 1 (for subscriptions) or byte 0 (for unsubscriptions) followed by the subscription body. Messages without a sub/unsub prefix may also be sent, but have no effect on subscription status.

[링크 : https://zeromq.org/socket-api/]

 

int zmq_device (int device, const void *frontend, const void *backend);
ZMQ_QUEUE starts a queue device
ZMQ_FORWARDER starts a forwarder device
ZMQ_STREAMER starts a streamer device

Queue device
ZMQ_QUEUE creates a shared queue that collects requests from a set of clients, and distributes these fairly among a set of services. Requests are fair-queued from frontend connections and load-balanced between backend connections. Replies automatically return to the client that made the original request.

This device is part of the request-reply pattern. The frontend speaks to clients and the backend speaks to services. You should use ZMQ_QUEUE with a ZMQ_XREP socket for the frontend and a ZMQ_XREQ socket for the backend. Other combinations are not documented.

Refer to zmq_socket(3) for a description of these socket types.

Forwarder device
ZMQ_FORWARDER collects messages from a set of publishers and forwards these to a set of subscribers. You will generally use this to bridge networks, e.g. read on TCP unicast and forward on multicast.

This device is part of the publish-subscribe pattern. The frontend speaks to publishers and the backend speaks to subscribers. You should use ZMQ_FORWARDER with a ZMQ_SUB socket for the frontend and a ZMQ_PUB socket for the backend. Other combinations are not documented.

Refer to zmq_socket(3) for a description of these socket types.

Streamer device
ZMQ_STREAMER collects tasks from a set of pushers and forwards these to a set of pullers. You will generally use this to bridge networks. Messages are fair-queued from pushers and load-balanced to pullers.

This device is part of the pipeline pattern. The frontend speaks to pushers and the backend speaks to pullers. You should use ZMQ_STREAMER with a ZMQ_PULL socket for the frontend and a ZMQ_PUSH socket for the backend. Other combinations are not documented.

Refer to zmq_socket(3) for a description of these socket types.

[링크 : http://api.zeromq.org/2-1:zmq-device]

'Linux API > linux' 카테고리의 다른 글

ipc 성능 비교  (0) 2022.09.21
posix message queue  (0) 2022.09.21
파일 존재유무 확인하기  (0) 2022.02.11
select, poll, epoll  (0) 2021.11.02
Unhandled fault: external abort on non-linefetch  (0) 2021.05.25
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2022. 2. 11. 11:06

tmpfs에 touch로 파일을 생성/삭제하면서 테스트 해보니

마우스 이벤트에 묶여있어도 cpu 점유율 이 크게 오르지 않는걸 봐서는 부하가 크지 않은 듯.

 

if( access( fname, F_OK ) == 0 ) {
    // file exists
} else {
    // file doesn't exist
}

[링크 : https://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c]

 

#include <unistd.h>
int access(const char *pathname, int mode);

The mode specifies the accessibility check(s) to be performed, and is either the value F_OK, or a mask consisting of the bitwise OR of one or more of R_OK, W_OK, and X_OK. F_OK tests for the existence of the file. R_OK, W_OK, and X_OK test whether the file exists and grants read, write, and execute permissions, respectively.

[링크 : https://linux.die.net/man/2/access]

 

F_OK 파일 존재여부
R_OK 파일 read 퍼미션 여부
W_OK 파일 write 퍼미션 여부
X_OK 파일 execute 퍼미션 여부

'Linux API > linux' 카테고리의 다른 글

posix message queue  (0) 2022.09.21
zeroMQ  (0) 2022.09.20
select, poll, epoll  (0) 2021.11.02
Unhandled fault: external abort on non-linefetch  (0) 2021.05.25
Stopped (tty input)  (0) 2021.05.21
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 11. 2. 10:44

개략적으로 보면.. select나 poll이나 비슷하게 이벤트 발생시 누가 발생했는지 찾아서 처리해야 하고

epoll은 이벤트 발생시 발생목록을 전달하여, 누가 발생했는지 찾을 필요 없이 바로 처리하면 된다.

다만 select는 1024가 한번에 다룰수 있는 최대 fd 갯수고

poll은 숫자제한은 없지만 선형 탐색을 해야하고, 1500 넘으면 느려진다고 하고

epoll이 1500 보다 클 경우는 유리한 듯.

 

select / poll / epoll

[링크 : https://niklasjang.github.io/backend/select-poll-epoll/]

[링크 : https://applefarm.tistory.com/144]

 

select

while(1)
{
   fd_num = select(...);
   if(fd_num == -1) break;
   else if(fd_num == 0 ) continue;

   for(int fd =0; fd < fd_max + 1; ++fd)
   {
      if(FD_ISSET(fd, &cpy_reads))
      {
          // TODO
      }
   }

   close(server_socket);
   return 0;
}

[링크 : https://ozt88.tistory.com/21]

 

poll

       #include <poll.h>
       #include <fcntl.h>
       #include <sys/types.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       int
       main(int argc, char *argv[])
       {
           int nfds, num_open_fds;
           struct pollfd *pfds;

           if (argc < 2) {
              fprintf(stderr, "Usage: %s file...\n", argv[0]);
              exit(EXIT_FAILURE);
           }

           num_open_fds = nfds = argc - 1;
           pfds = calloc(nfds, sizeof(struct pollfd));
           if (pfds == NULL)
               errExit("malloc");

           /* Open each file on command line, and add it 'pfds' array. */

           for (int j = 0; j < nfds; j++) {
               pfds[j].fd = open(argv[j + 1], O_RDONLY);
               if (pfds[j].fd == -1)
                   errExit("open");

               printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);

               pfds[j].events = POLLIN;
           }

           /* Keep calling poll() as long as at least one file descriptor is
              open. */

           while (num_open_fds > 0) {
               int ready;

               printf("About to poll()\n");
               ready = poll(pfds, nfds, -1);
               if (ready == -1)
                   errExit("poll");

               printf("Ready: %d\n", ready);

               /* Deal with array returned by poll(). */

               for (int j = 0; j < nfds; j++) {
                   char buf[10];

                   if (pfds[j].revents != 0) {
                       printf("  fd=%d; events: %s%s%s\n", pfds[j].fd,
                               (pfds[j].revents & POLLIN)  ? "POLLIN "  : "",
                               (pfds[j].revents & POLLHUP) ? "POLLHUP " : "",
                               (pfds[j].revents & POLLERR) ? "POLLERR " : "");

                       if (pfds[j].revents & POLLIN) {
                           ssize_t s = read(pfds[j].fd, buf, sizeof(buf));
                           if (s == -1)
                               errExit("read");
                           printf("    read %zd bytes: %.*s\n",
                                   s, (int) s, buf);
                       } else {                /* POLLERR | POLLHUP */
                           printf("    closing fd %d\n", pfds[j].fd);
                           if (close(pfds[j].fd) == -1)
                               errExit("close");
                           num_open_fds--;
                       }
                   }
               }
           }

           printf("All file descriptors closed; bye\n");
           exit(EXIT_SUCCESS);
       }

[링크 : https://man7.org/linux/man-pages/man2/poll.2.html]

 

epoll

int epoll_fd = epoll_create(EPOLL_SIZE);
struct epoll_event* events = malloc(sizeof(struct epoll_event)*EPOLL_SIZE);
struct epoll_event init_event;
init_event.events = EPOLLIN;
init_event.data.fd = server_socket;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &init_event);
while(TRUE)
{
   int event_count = epoll_wait(epoll_fd, events, EPOLL_SIZE, -1);
   if( event_count = -1 ) break;
   for( int i = 0 ; i < event_count; ++i )
   {
      if(events[i].data.fd == server_socket) //서버 소켓에 이벤트
      { //accept 처리 ... init_event.events = EPOLLIN;
         init_event.data.fd = new_client_socket;
         epoll_ctl(epoll_fd, EPOLL_CTL_ADD, new_client_socket, &init_event);
      }
      else //이벤트가 도착한 소켓들
      {
            //read, write, closesocket처리
      }
   }
}

closesocket(server_socket);
close(epoll_fd);
return 0;

[링크 : https://ozt88.tistory.com/21]

 

 

 

+

오래된 글이지만 벤치마크 결과 poll/select는 거의 동일한 성능이고

fd 갯수가 늘어갈수록 느려지지만, epoll이나 kqueue의 경우 일정 상한 이상으로는 성능이 유지되는 경향을 보인다.

[링크 : https://monkey.org/~provos/libevent/libevent-benchmark.jpg]

[링크 : https://kldp.org/node/46542]

 

일반적으로 소켓수가 1500이하일때는 퍼모먼스 차이는 거의 없는것으로 알고 있습니다.

select poll epoll 의 성능차이는 5000 이상부터 급격히 달라집니다.

[링크 : http://foroum.gpgstudy.com/forum/viewtopic.php?t=12610]

'Linux API > linux' 카테고리의 다른 글

zeroMQ  (0) 2022.09.20
파일 존재유무 확인하기  (0) 2022.02.11
Unhandled fault: external abort on non-linefetch  (0) 2021.05.25
Stopped (tty input)  (0) 2021.05.21
linux gpio interrupt poll?  (0) 2021.05.04
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 5. 25. 15:00

mmap()으로 특정 메모리 영역을 접근하는데

이상한 순서로 에러 메시지가 뒤죽박죽 되어 나와서 겨우겨우 복구(?) 해봤더니 더 멘붕오는 듯한 용어만 잔뜩 -_-

Unhandled fault: external abort on non-linefetch (0x1818) at 0x70000000
pgd = cdbbc000
Error: [70000000] *pgd=0dbc3831, *pte=70000743, *ppte=70000c33

 

ppte는 약어를 못 찾음 (느낌은 pte에 대한 pointer 아닐까 싶긴 하지만..)

PGD : Page Global Directory
PTE : Page Table Entries

[링크 : https://www.kernel.org/doc/gorman/html/understand/understand006.html]

 

(0x1818) 음.. 딱 적절한 나의 마음을 나타내는 값은 ifsr 레지스터 라는데

The values in parenthesis are the ifsr (instruction fault status) register

[링크 : https://stackoverflow.com/questions/15889483/what-do-these-kernel-panic-errors-mean]

 

레지스터값의 의미를 요약하면 다음과 같은데

AXI Slave error로 인해서 abort가 발생,
write access가 abort를 발생
D1 domain?
precise external abort, nontranslation

도대체 무슨 말이야!!!

 




SD
Indicates whether an AXI Decode or Slave error caused an abort. This bit is only valid for external aborts. For all other aborts this bit Should Be Zero:
0 = AXI Decode error caused the abort, reset value
1 = AXI Slave error caused the abort.

RW
Indicates whether a read or write access caused an abort:
0 = read access caused the abort, reset value
1 = write access caused the abort.

Domain
Indicates which one of the 16 domains, D15-D0, is accessed when a data fault occurs. This field takes values 0-15.

Status
Indicates the type of exception generated. To determine the data fault, bits [12] and [10] must be used in conjunction with bits [3:0]. The following encodings are in priority order, 1 is the highest:

0b000001 alignment fault
0b000100 instruction cache maintenance fault
0bx01100 L1 translation, precise external abort
0bx01110 L2 translation, precise external abort
0b011100 L1 translation precise parity error
0b011110 L2 translation precise parity error
0b000101 translation fault, section
0b000111 translation fault, page
0b000011 access flag fault, section
0b000110 access flag fault, page
0b001001 domain fault, section
0b001011 domain fault, page
0b001101 permission fault, section
0b001111 permission fault, page
0bx01000 precise external abort, nontranslation
0bx10110 imprecise external abort
0b011000 imprecise error, parity or ECC
0b000010 debug event.

[링크 : https://developer.arm.com/documentation/.../c5--data-fault-status-register]

 

[링크 : https://github.com/brgl/busybox/blob/master/miscutils/devmem.c]

'Linux API > linux' 카테고리의 다른 글

파일 존재유무 확인하기  (0) 2022.02.11
select, poll, epoll  (0) 2021.11.02
Stopped (tty input)  (0) 2021.05.21
linux gpio interrupt poll?  (0) 2021.05.04
Floating point exception  (0) 2021.04.05
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 5. 21. 17:33

stdin을 통해 입력을 받아 작동하는 프로그램을 쉘에서 실행하고 백드라운드로 돌리니 멈춘다?!

bg
[1] /test
#
[1]+  Stopped (tty input)        /test

 

[링크 : https://topic.alibabacloud.com/...-stopped-tty-input_1_16_30150438.html]

[링크 : https://unix.stackexchange.com/questions/294471/backgrounded-job-keeps-stopping]

 

아무튼 SIGTTIN이 들어와서 그렇다고 하는데

간단하게는.. 해당 시그널을 무시하면 되는거고..

다른 방법은 좀 더 고민해 봐야 할 듯 -_-

 

void
init_shell ()
{

  /* See if we are running interactively.  */
  shell_terminal = STDIN_FILENO;
  shell_is_interactive = isatty (shell_terminal);

  if (shell_is_interactive)
    {
      /* Loop until we are in the foreground.  */
      while (tcgetpgrp (shell_terminal) != (shell_pgid = getpgrp ()))
        kill (- shell_pgid, SIGTTIN);

      /* Ignore interactive and job-control signals.  */
      signal (SIGINT, SIG_IGN);
      signal (SIGQUIT, SIG_IGN);
      signal (SIGTSTP, SIG_IGN);
      signal (SIGTTIN, SIG_IGN);
      signal (SIGTTOU, SIG_IGN);
      signal (SIGCHLD, SIG_IGN);

      /* Put ourselves in our own process group.  */
      shell_pgid = getpid ();
      if (setpgid (shell_pgid, shell_pgid) < 0)
        {
          perror ("Couldn't put the shell in its own process group");
          exit (1);
        }

      /* Grab control of the terminal.  */
      tcsetpgrp (shell_terminal, shell_pgid);

      /* Save default terminal attributes for shell.  */
      tcgetattr (shell_terminal, &shell_tmodes);
    }
}

[링크 : https://www.gnu.org/software/libc/manual/html_node/Initializing-the-Shell.html]

 

Macro: int SIGTTINA process cannot read from the user’s terminal while it is running as a background job. When any process in a background job tries to read from the terminal, all of the processes in the job are sent a SIGTTIN signal. The default action for this signal is to stop the process. For more information about how this interacts with the terminal driver, see Access to the Terminal.

[링크 : https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html]

'Linux API > linux' 카테고리의 다른 글

select, poll, epoll  (0) 2021.11.02
Unhandled fault: external abort on non-linefetch  (0) 2021.05.25
linux gpio interrupt poll?  (0) 2021.05.04
Floating point exception  (0) 2021.04.05
실행파일 not fount, FATAL: kernel too old  (0) 2021.04.05
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 5. 4. 17:55

MCU 처럼 gpio trigger interrupt를 하려면 리눅스 드라이버로 처리해야 한다고 하고

유저 어플리케이션에서는 poll로 보다가 뜨면 callback 함수 실행해주는 수 밖에 없는 듯..

 

[링크 : https://stackoverflow.com/questions/56166622/how-to-handle-gpio-interrupt-like-handling-in-linux-userspace]

[링크 : https://github.com/luisaburini/GPIO-interrupt/blob/master/gpio-poll.c]

[링크 : https://www.kernel.org/doc/Documentation/gpio/sysfs.txt]

 

+

2021.05.06

lseek() 만으로는 초기화가 안되고 read도 해주어야 초기화 되네.. 장치 특성인가?

그리고 대충(!) 하다 보니 실수로 poll 등록시 POLLIN 만 등록해놓고 POLLPRI를 체크하고 있었...

'Linux API > linux' 카테고리의 다른 글

Unhandled fault: external abort on non-linefetch  (0) 2021.05.25
Stopped (tty input)  (0) 2021.05.21
Floating point exception  (0) 2021.04.05
실행파일 not fount, FATAL: kernel too old  (0) 2021.04.05
spi 통신 예제(linux)  (0) 2021.01.28
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 4. 5. 16:44

이런 에러 처음 겪네 -_-

 

runtime DIV/0 에러에 가깝다고 해야하나..

(문제는 전부 char 형인데 뜬금없이 float point..)

[링크 : https://stackoverflow.com/questions/4236853/floating-point-exception-c-why-and-what-is-it]

[링크 : https://kldp.org/node/122753]

[링크 : https://www.acmicpc.net/board/view/21892]

 

혹시나 해서 gdb 물려서 실행해보니

Program received signal SIGFPE, Arithmetic exception.

 

이름은 Floating Point Exception 에서 유래하긴 했는데

"0으로 나누기와 오버플로우를 포함한 모든 산술에러"에서 발생한다고 한다.

Macro: int SIGFPE

The SIGFPE signal reports a fatal arithmetic error. Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow. If a program stores integer data in a location which is then used in a floating-point operation, this often causes an “invalid operation” exception, because the processor cannot recognize the data as a floating-point number.

Actual floating-point exceptions are a complicated subject because there are many types of exceptions with subtly different meanings, and the SIGFPE signal doesn’t distinguish between them. The IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985 and ANSI/IEEE Std 854-1987) defines various floating-point exceptions and requires conforming computer systems to report their occurrences. However, this standard does not specify how the exceptions are reported, or what kinds of handling and control the operating system can offer to the programmer.

[링크 : https://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html]

'Linux API > linux' 카테고리의 다른 글

Stopped (tty input)  (0) 2021.05.21
linux gpio interrupt poll?  (0) 2021.05.04
실행파일 not fount, FATAL: kernel too old  (0) 2021.04.05
spi 통신 예제(linux)  (0) 2021.01.28
linux USB bulk 통신  (0) 2020.10.21
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 4. 5. 10:53

빌드해서 올리는데 파일이 있는데 없다고?!?!

혹시나 해서 보는데 target에 file도 없어 ㅠㅠㅠㅠ 아놔 -_-

아무튼 

파일이 없는건

zynq> ./test
-sh: ./test: not found

zynq> ls -al /lib/ld-
ld-2.13.so     ld-linux.so.3

zynq> ls -al /lib/ld-linux.so.3
lrwxrwxrwx    1 root     root            10 Nov 27  2012 /lib/ld-linux.so.3 -> ld-2.13.so

zynq> ./test
FATAL: kernel too old
Aborted

 

/lib/ld-linux-armhf.so.3 와 /lib/ld-linux.so 의 차이 -_-

아니 저정도면 실행시에 링크파일이 없다고 에러나와줘야지 ㅠㅠ

왜 자기 자신이 없다고 에러가 나는게야!!

$ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 4.9.0, with debug_info, not stripped

 

아무튼 빡쳐서(!) static 링크해서 빌드하고 실행했더니

$ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 4.9.0, with debug_info, not stripped

 

야이!!!

zynq> ./test
FATAL: kernel too old
Aborted

 

에라이 걍 컴파일러 바꿔 -_-

[링크 : https://ggpapa.tistory.com/36]

[링크 : https://blog.naver.com/calb30095/221005114736]

'Linux API > linux' 카테고리의 다른 글

linux gpio interrupt poll?  (0) 2021.05.04
Floating point exception  (0) 2021.04.05
spi 통신 예제(linux)  (0) 2021.01.28
linux USB bulk 통신  (0) 2020.10.21
linux open() 과 8진법  (0) 2020.09.28
Posted by 구차니

댓글을 달아 주세요

Linux API/linux2021. 1. 28. 13:59

쓸일이 곧 생길게야.... (동공지진)

 

[링크 : https://github.com/torvalds/linux/blob/master/tools/spi/spidev_test.c]

+ 2021.02.08

 

It's easy to be confused here, and the vendor documentation you'll
find isn't necessarily helpful.  The four modes combine two mode bits:

 - CPOL indicates the initial clock polarity.  CPOL=0 means the
   clock starts low, so the first (leading) edge is rising, and
   the second (trailing) edge is falling.  CPOL=1 means the clock
   starts high, so the first (leading) edge is falling.

 - CPHA indicates the clock phase used to sample data; CPHA=0 says
   sample on the leading edge, CPHA=1 means the trailing edge.

   Since the signal needs to stablize before it's sampled, CPHA=0
   implies that its data is written half a clock before the first
   clock edge.  The chipselect may have made it become available.

[링크 : https://www.kernel.org/doc/Documentation/spi/spi-summary]

Posted by 구차니

댓글을 달아 주세요

Linux API/linux2020. 10. 21. 11:50

 

 

[링크 : https://stackoverflow.com/questions/15308770/read-usb-bulk-message-on-linux]

Posted by 구차니

댓글을 달아 주세요