UNIXSP_HP

advertisement
1-1. Executing a New Program
Exec : replaces the current process with the
new program
execlp
execl
create argv
create argv
execvp
execv
convert
file to
path
execle
create argv
add
envp
execve
system
call
1-2. 프로세스의 종료 : exit()
_exit
return
_exit
return
user
functions
exit
handler
...
call
main
function
exit
exit
function
return
call
exit
handler
call
C start-up
routine
_exit
exec
Kernel
standard I/O
cleanup
user
process
1-3. Exiting and Waiting
Values returned by the wait system call
Process
called exit
argument to exit
Signal
terminated
process
0x00
Process
stopped
0x00
signal number
core flag(0/1)
signal number
0x7f
Posix.1 specifies termination status as the Macro.
Macro
Description
WIFEXITED
(status)
WEXITSTATUS(status)
WIFSIGNALED
(status)
WTERMSIG(status)
WCOREDUMP(status)
WIFSTOPPED
(status)
WSTOPSIG(status)
2-1. File systems Ⅰ
disk
drive
partition
file
system
partition
i-list
partition
Directory blocks &
Data blocks
boot block
super block
i-node i-node i-node i-node
2-2. File systems Ⅱ
directory blocks and data blocks
i-list
i-node i-node
mydir
dirA
fileA
fileB
fileB.ln
data
block1
i-node
data
block
directory
block(dirA)
data
block2
directory
block(mydir)
i-node
i-node
number
filename
(fileA)
i-node
number
filename
(filleB.ln)
i-node
number
dirname
(dirA)
i-node
number
filename
(filleB)
3-1. Blocking Signals & Manipulate Signal Sets
<sigprocmask.c>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
int main() {
sigset_t toblock;
<sigpending.c>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
int main() {
sigset_t toblock, checkblock;
sigemptyset(&toblock);
sigemptyset(&checkblock);
sigaddset(&toblock, SIGINT);
sigemptyset(&toblock);
sigaddset(&toblock, SIGINT);
sigprocmask(SIG_BLOCK, &toblock,
(sigset_t *)NULL);
sleep(5);
sigpending(&checkblock);
if (sigismember(&checkblock, SIGINT))
printf("^C pressed!!!\n");
sleep(5);
sigprocmask(SIG_UNBLOCK, &toblock,
(sigset_t *)NULL);
sigprocmask(SIG_BLOCK, &toblock,
(sigset_t *)NULL);
sleep(10);
sigprocmask(SIG_UNBLOCK, &toblock,
(sigset_t *)NULL);
printf("a SIGINT is ignored!!!\n");
}
return 0;
}
printf("a SIGINT is ignored!!!\n");
return 0;
3-2. Interrupting System Calls
<testrestart.c>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
void handler(int);
main()
{ struct sigaction act;
int len;
char line[100];
act.sa_handler=handler;
act.sa_flags=SA_RESTART;
(void)sigemptyset(&act.sa_mask);
if (sigaction(SIGINT, &act, 0)==-1)
{ perror(“sigaction error”);
exit(1);
}
write(1, “Input the string:”, 18);
len=read(0, line, sizeof(line));
write(1, “string read :”, 13);
write(1, line, len);
}
void handler(int signo)
{
write(1, “caught signal -> INT\n”, 21);
write(1, “Input the string:”, 18);
}
3-3. Non-Local GOTO - setjmp
<setjmp.c>
#include <stdio.h>
#include <setjmp.h>
#include <unistd.h>
#include <signal.h>
while (1)
{ if (setjmp(env))
if(count<2) count++;
else break;
alarm(10);
write(1, “Input data :”, 12);
if ((n=read(0, buf, sizeof(buf)) < 0)
{ perror(“read error”);
exit(1);
}
alarm(0);
break;
}
void handler(int);
jmp_buf env;
main()
{
struct sigaction act;
char buf[100];
int n, count=0;
act.sa_handler=handler;
act.sa_flags=0;
(void)sigemptyset(&act.sa_mask);
if (sigaction(SIGALRM, &act, 0)==-1)
{
perror(“sigaction”);
exit(1);
}
}
void handler(int signo)
{
write(1, “Time expired!\n”, 15);
longjmp(env, 1);
}
5-1. System V IPC
Types : Message queue, Shared memory, Semaphore
Each IPC structure in the kernel is refferred to by a
nonnegative integer identifier.
Permission structure (공통)
struct ipc_perm {
uid_t
uid;
/* owner’s effective user id */
gid_t
gid;
/* owner’s effective group id */
uid_t
cuid; /* creator’s effective user id */
gid_t
cgid; /* creator’s effective group id */
mode_t mode; /* access modes */
ulong seg; /* slot usage sequence number */
key_t key; /* key */
};
6-1. Shared Memory I
Shared Memory allows two or more processes
to share a given region of memory.
Shared Memory is the fastest form of IPC
(because the data does not need to be copied
between the client and server)
Movement of data between client and server
client
server
client
Shared
memory
server
FIFO, PIPE
or MQ
Output
file
kernel
Input
file
Output
file
kernel
Input
file
6-2. Shared Memory II
struct shmid_ds {
struct ipc_perm shm_perm;
int
shm_segsz;
struct XXX shm_YYY;
ushort shm_lkcnt;
pid_t
shm_lpid;
pid_t
shm_cpid;
ulong
shm_nattch;
ulong
shm_cattach;
time_t
shm_atime;
time_t
shm_dtime;
time_t
shm_ctime;
}
System V
Page1
Process1
Page2
Shared Area
A Real
Shared Memory!!
Page3
Page4
Process2
Page5
Shared Area
Page6
Physical Memory
page
Virtual Memory Space
6-3. Shared Memory III
Functions
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
-. Getting : int shmget(key_t key, int size, int flag);
-. Operating :
void *shmat(int shmid, void *addr, int flag);
void *shmdt(void *addr);
-. Controlling :
0 , SHM_RDONLY
int shmctl(int shmid, int cmd,
struct shmid_ds *buf);
IPC_STAT,
IPC_SET, IPC_RMID,
SHM_LOCK,
SHM_UNLOCK
shmlistener.c
shmtalker.c
int main(int argc, char **argv) {
key_t key;
int shmid;
void *addr;
void *shmaddr;
char buf[1024];
void handler(int dummy) {;}
int main() {
int shmid;
key_t key;
void *shmaddr;
sigset_t mask;
char buf[1024];
if (argc != 2) {
perror("argc");
exit(1);
}
key = ftok("/etc/passwd", 1);
shmid = shmget(key, 1024, 0);
key = ftok("/etc/passwd", 1);
shmid = shmget(key, 1024, IPC_CREAT | 0666);
sigfillset(&mask);
sigdelset(&mask, SIGUSR1);
sigset(SIGUSR1, handler);
printf("listener wait for talker\n");
sigsuspend(&mask);
shmaddr = shmat(shmid, NULL, 0);
strcpy(shmaddr, "Hello, I'm talker\n");
kill(atoi(argv[1]), SIGUSR1);
}
shmaddr = shmat(shmid, NULL, 0);
strcpy(buf, shmaddr);
printf("listener received : %s\n", buf);
printf("mmap send.\n");
msync(shmaddr, 1024, MS_SYNC);
strcpy(buf, shmaddr);
printf("Listener said : %s\n", buf);
sleep(3);
system("ipcs");
shmdt(shmaddr);
return 0;
}
strcpy(shmaddr, "Have a nice day.");
msync(shmaddr, 1024, MS_SYNC);
sleep(10);
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
7-1. Semaphores I
Semaphores are not used for exchanging large
amounts of data.
Semaphores are intended to let multiple processes
synchronize their operations.
A semaphore is a counter used to provide access
to a shared data object for multiple processes.
process A
process B
Semaphore 0 or 1
kernel
7-2. Semaphores II
Kernel data structures for a semaphore set
semid
struct sem {
ushort
pid_t
ushort
ushort
};
struct semid_ds
sem_perm
stucture
semval;
sempid;
semncnt;
semzcnt;
struct semid_ds {
struct ipc_perm sem_perm;
struct sem *sem_base;
ushort sem_nsems;
time_t sem_otime;
time_t sem_ctime;
}
sem_base
sem_nsems
sem_otime
semval
[0]
sempid
[0]
semncnt
[0]
semzcnt
[0]
semval
[1]
sempid
[1]
semncnt
[1]
semzcnt
[1]
sem_ctime
kernel
7-3. Semaphores III
Functions
-. Getting : int semget(key_t key, int nsems, int flag);
-. Operating :
int semop(int semid, struct sembuf *sops,
size_t nops);
struct sembuf {
ushort sem_num;
short sem_op;
short sem_flg;
}
IPC_NOWAIT, SEM_UNDO
-. Controlling :
int semctl(int semid, int semnum, int cmd,
union semun arg);
union semun {
int
val;
struct semid_ds *buf;
ushort
*array;
}
IPC_STAT, IPC_SET,
IPC_RMID, GETVAL,
SETVAL, GETALL,
SETALL
mysem.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#define DUMMY 0
#define COUNT 3
main(int argc, char *argv[])
{ key_t ipckey;
int
semid, pid, creator, i;
struct sembuf lock={0, -1, SEM_UNDO};
struct sembuf unlock={0, 1, SEM_UNDO};
setbuf(stdout, (char *)NULL);
ipckey=ftok(argv[0], 1);
if ((semid=
semget(ipckey, 1,IPC_CREAT | IPC_EXCL
| 0666)) != -1)
creator=1;
else
if ((semid=semget(ipckey, 1, 0)) == -1)
{ perror(“semget failed”);
exit(1);
}
else
creator=0;
if (creator)
{ if (semctl(semid, 0, SETVAL, 1) == -1)
{ perror(“semctl SETVAL failed”);
exit(2);
}
}
pid=getpid();
for(i=0; i<COUNT; i++)
{ if (semop(semid, &lock, 1)==-1)
{ perror(“semop lock failed”);
exit(3);
}
printf(“\t[%d]locking\n”, pid);
sleep(3);
printf(“\t[%d]unlocking\n”, pid);
if (semop(semid, &unlock, 1) == -1)
{ perror(“semop unlock failed”);
exit(4);
}
}
if (creator)
{ sleep(5);
if (semctl(semid, DUMMY, IPC_RMID,
DUMMY) == -1)
{ perror(“semctl IPC_RMID failed”);
exit(5);
}
}
} /* end of main */
8-1. Message Queue I
Linked list of message stored within the kernel and
identified by message queue Identifier.
Kernel data structures for a message queue
struct msqid_ds {
struct ipc_perm msg_perm;
sturct msg *msg_first;
struct msg *msg_last;
ulong msg_cbytes;
ulong msg_qnum;
ulong msg_qbytes;
pid_t msg_lspid;
pid_t msg_lrpid;
time_t msg_stime;
time_t msg_rtime;
time_t msg_ctime;
};
struct msqid_ds
msq_id
msg_perm
structure
msg_first
msg_last
link
link
NULL
type
type
type
length
length
length
data
data
data
.
.
msg_ctime
kernel
8-2. Message Queue II
Functions
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
-. Getting : int msgget(key_t key, int flag);
IPC_CREAT,
-. Operating :
IPC_EXCL
int msgsnd(int msqid, const void *ptr,
size_t nbytes, int flag);
IPC_NOWAIT
int msgrcv(int msqid, void *ptr,
size_t nbytes, long type, int flag);
-. Controlling :
int msgctl(int msqid, int cmd,
IPC_STAT, IPC_SET,
struct msqid_ds *buf);
IPC_RMID
8-3. Multiplexing Messages
The purpose of having a type, associated with each
message is to allow multiple processes to
multiplex messages on to a single queue.
client1
pid=123
type=1
type=123
client2
pid=456
type=1
type=456
client3
pid=789
type=1
Message queue
type=1
type=123 or 456 or 789
Server
type=789
9-1. Memory Mapping Files - mmap
Page1
Page2
Process1
Shared Area
Memory
Mapped
File
Page3
Page4
Page5
Process2
Shared Area
Memory
Mapped
File
Page6
Page7
Physical Memory page
Virtual Memory
Space
File
File System
9-2. Memory Mapping Files - Example
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
addr=mmap(NULL, statbuf.st_size, PROT_READ,
MAP_SHARED, fd (off_t)0);
main(int argc, char *argv[])
{ int fd;
caddr_t addr;
struct stat statbuf;
close(fd);
if (addr == MAP_FAILED)
{ perror(“mmap”);
exit(1);
}
write(1, addr, statbuf.st_size);
return(0);
}
if (argc != 2)
{ fprintf(stderr,
“Usage: mymmap filename\n”);
exit(1);
}
if (stat(argv[1], &statbuf) == -1)
{ perror(“stat”);
exit(1);
}
if ((fd=open(argv[1], O_RDONLY))==-1)
{ perror(“open”);
exit(1);
}
<mmap.c>
Sizing a File
#include <unistd.h>
int truncate(const char *path, off_t length);
int ftruncate(int fildes, off_t length);
10-1. Asynchronous I/O
SIGIO : asynchronous I/O in 4.3 BSD
1) Establish a signal handler
 sigaction(SIGIO, &act, 0);
2) Set the process ID to receive the signal for the
descriptior.
 ioctl(fd, FIOSETOWN, &pid); /* pid=getpid(); */
3) Enable asynchronous I/O on the descriptor.
 ioctl(fd, FIOASYNC, &arg); /* arg=1 */
SIGPOLL : asynchronous I/O in SVR4
1) Establish a signal handler
 sigaction(SIGPOLL, &act, 0);
2) Enable asynchronous I/O for a stream device
 ioctl(fd, I_SETSIG, S_RDNORM);
Limitation : There is only one signal per process.
10-2. I/O Multiplexing
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
int select(int maxfdp1, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *tvptr);

FD_ZERO(&rset);
FD_CLR(fd, &rset)
FD_SET(fd, &rset);
if (FD_ISSET(fd, &rset)) …
NULL :Wait forever
fd0 fd1 fd2
readfds
0
0
0
……
One bit per possible
descriptor
#include <stropts.h>
#include <poll.h>
int poll(struct pollfd fdarray[], unsigned long nfds, int timeout);
struct pollfd {
int
fd;
/* file descriptor to check */
short event; /* events of interest on fd */
short revents; /* events that occurred on fd */
};
INFTIM(-1) : Wait forever
0 : Don’t wait
positive : Wait timeout
milliseconds
11-1. Treads Overview
Definition : an independent sequence of execution of
program code inside a UNIX process.
Calling function vs creating thread
funt_call();
Pthread_create();
Created thread
Called function
Calling program
Creating program
11-2. Treads Overview II
Single Thread vs Multi Threads
Register
s
Memory
Memory
Heap
Heap
정적자료
Stack
Code
<단일 Thread 형
Process>
정적자료
Thread
Thread
Thread
Register
s
Register
s
Register
s
Stack
Stack
Stack
Code
<멀티 Thread 형
Process>
11-3. Two model of Thread Control I
User-level Thread
: are not visible outside of the process
User-level thread
Runtime
mapping
Kernel entity
-. Extremely low overhead
-. The threads can share only processor resources
allocated to their encapsulating process.
11-4. Two model of Thread Control II
Kernel-level Thread
: are scheduled just like individual process
User-level thread
Kernel entity
-. The kernel is aware of thread as a schedulable
entity  expensive
-. This model can take advantage of the multiprocessor.
11-5. Hybrid Thread Model
This model have advantages of both user-level and
kernel-level models by providing two levels of
control
User-level thread
Kernel entity
11-6. Creating a Thread
#include <pthread.h>
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void (*start_routine)(void *),
void *arg);
pthread_create()
pthread_t *thread –> thread_ID
pthread_attr_t *attr
–> thread attributes
void *(*start_routine) (void *)
–> function pointer
void *arg
–> pointer to the data to be
passed to the call
#include <pthread.h>
void pthread_exit(void *value_ptr);
int pthread_cancel(pthread_t
target_thread);
int pthread_join(pthread_t thread,
void **value_ptr);
pthread_exit()
->Terminates thread itself
pthread_cancel()
->Terminates thread specified tid
pthread_join()
->Wait for specified thread
are finished
11-7. Basic Example
<pth_create.c>
#include <pthread.h>
#include <stdio.h>
void *pthread1(void *dummy) {
sleep(1);
printf("Hello.. I'm pthread1\n");
pthread_exit(NULL);
}
void *pthread2(void *dummy) {
sleep(2);
printf("Hello.. I'm pthread2.. %d\n", (int)dummy);
pthread_exit(NULL);
}
int main() {
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, pthread1, NULL);
pthread_create(&tid2, NULL, pthread2, (void *)3);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
11-8. Synchronization
Synchronization methods
– Mutual exclusion (mutex) locks
• When another thread locks same mutex, my
thread is suspended until another thread
releases same mutex
– Multiple-reader-single-writer (rwlock) locks
• Same as mutex locks, but read-lock is more
free access resources.
– Semaphore locks
• Enables two or more locks
– Condition variable locks
• Producer vs Consumer problem
11-9. Synchronization - Mutex
<mutex.c>
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t
*obj);
int pthread_mutex_lock(pthread_mutex_t
*obj);
int pthread_mutex_unlock(pthread_mutex_t
*obj);
int pthread_mutex_trylock(pthread_mutex_t
*obj);
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex
= PTHREAD_MUTEX_INITIALIZER;
void *pthread1(void *dummy) {
sleep(2);
pthread_mutex_lock(&mutex);
printf("Hello.. I'm pthread1\n");
sleep(2);
pthread_mutex_unlock(&mutex);
printf("unlocked.. (1)\n");
}
void *pthread2(void *dummy) {
sleep(1);
pthread_mutex_lock(&mutex);
printf("Hello.. I'm pthread2. I'll rest 3 seconds.\n");
sleep(3);
pthread_mutex_unlock(&mutex);
printf("unlocked.. (2)\n");
}
int main() {
<Same as ‘the Basic Example’>
return 0;
}
Download