Consider Letting inetd Launch Your Application
inetd daemon Problems starting with /etc/rc(without inet daemon) All the servers contains nearly identical startup code Each daemon takes a slot in process table, but asleep most of time /etc/inetd.conf file specifies the services that the superserver inetd is to handle
Steps performed by inetd dup2(sockfd, 0); dup2(sockfd, 1); dup2(sockfd, 2); close(sockfd); Open descriptor 들은 fork 시 copy 되고 Exec 후에도 유지된다. Exec 후에 Peer 를 알 수 있는 방법은 ?
Consider Using Two TCP Connections
Concurrent Input/Output processes One-connection architecture Xout 에서 send 할 때 pending error 는 xin 에서 recv 해야 알 수 있다 Xin mp xout 으로 알려 줘야 함 Two connection architecture 별도의 connection 에 대해 socket pending error 가 있는지 testing 가능 Using select() readability
Example xout1.c:
Interprocess Communication via UNIX Domain Protocols
UNIX Domain Sockets A UNIX IPC method Absolute pathname is used instead of protocol address and port number Stream socket: similar to TCP socket Datagram socket: similar to UDP socket An unreliable datagram service that preserves record boundary may be discarded (receiver 가 빨리 읽어내지 못하면 ) may be discarded (receiver 가 빨리 읽어내지 못하면 ) Normally, used for passing descriptor Usage of UNIX domain socket Twice as fast as a TCP socket on the same host Used when passing descriptors between processes on the same host (using sendmsg(), recvmsg()); Provides client’s credentials (UID, GID) to the server
UNIX Domain Stream Client/Server unixdomain/unixstrcli01.c unixdomain/unixstrserv01.c UNP
UNIX Domain Datagram Protocol unixdomai/unixdgcli01.c unixdomai/unixdgserv01.c Binding client address (pathname) is necessary to identify client UNP
Threads
Introduction Process Overhead in process creation(fork) memory is copied all descriptor are duplicated IPC required to pass information between parent and child processes after fork Thread: light-weight process All threads within a process share the same global memory raises synchronization and mutual exclusion problems times faster than process creation Many different thread implementation Pthread: Posix thread
Shared and Own data in Threads Shared information process instructions most data open files (e.g., descriptor) signal handlers and signal dispositions current working directory user and group IDs Thread’s own data thread ID set of registers stack errno signal masks priority
Thread Creation and Termination Thread attributes priority initial stack size daemon thread or not: detached or joinable thread default: NULL Terminating a thread implicit termination when thread starting function returns explicit termination pthread_exit exit
A Simpler Version of str_cli using Threads UNP
TCP Echo Server using Threads threads/tcpserv01.c threads/tcpserv02.c – more portable UNP
Non-determinism causes time-dependent errors Non-determinism (Race Condition) in C int ndone = 0; /* shared variable */ Thread A: Thread B: ndone++;done--; Compiled output (ASM) LOAD ndone INCR LOAD ndone DECR STORE ndone Result ?? An instruction is atomic (indivisible), but a statement may be divisible !! Shared variables should be used in mutually exclusive manner Critical region: code region accessing share variable
Mutual Exclusion Shared data! Critical region For shared data count
Condition Variables wait for condition and wake up one thread wait for condition and wake up all thread Shared variable Critical section mutex condition wait signal lock unlock
Example: Condition Variables