9\10\11\12 Finished.
This commit is contained in:
parent
c9fbf46d4b
commit
e29fa7be44
16
10/signal/pause.c
Normal file
16
10/signal/pause.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void sig_alarm(int signo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
if(signal(SIGALRM, sig_alarm) == SIG_ERR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
alarm(3);
|
||||||
|
pause();
|
||||||
|
return alarm(0);
|
||||||
|
}
|
20
10/signal/pause2.c
Normal file
20
10/signal/pause2.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static jmp_buf env_alrm;
|
||||||
|
|
||||||
|
static void sig_alrm(int signo) {
|
||||||
|
longjmp(env_alrm, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
if(signal(SIGALRM, sig_alrm) == SIG_ERR)
|
||||||
|
return -1;
|
||||||
|
if(setjmp(env_alrm) == 0) {
|
||||||
|
alarm(3);
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
50
10/signal/pending.c
Normal file
50
10/signal/pending.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void sig_quit(int);
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
sigset_t newmask, oldmask, pendmask;
|
||||||
|
|
||||||
|
if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
|
||||||
|
printf("can't catch SIGQUIT\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigemptyset(&newmask);
|
||||||
|
sigaddset(&newmask, SIGQUIT);
|
||||||
|
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
|
||||||
|
printf("SIG_BLOCK error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
if (sigpending(&pendmask) < 0) {
|
||||||
|
printf("sigpeding error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (sigismember(&pendmask, SIGQUIT)) {
|
||||||
|
printf("\nSIGQUIT pending\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
|
||||||
|
printf("SIG_SETMASK error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("SIGQUIT unblocked\n");
|
||||||
|
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_quit(int signo) {
|
||||||
|
printf("caught SIGQUIT\n");
|
||||||
|
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
|
||||||
|
printf("can't reset SIGQUIT");
|
||||||
|
}
|
||||||
|
}
|
35
10/signal/read.c
Normal file
35
10/signal/read.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void sig_alrm(int);
|
||||||
|
static jmp_buf env_alrm;
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int n;
|
||||||
|
char line[256];
|
||||||
|
|
||||||
|
if(signal(SIGALRM, sig_alrm) == SIG_ERR) {
|
||||||
|
printf("signal(SIGALRM) error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setjmp(env_alrm) != 0) {
|
||||||
|
printf("read timeout\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(5);
|
||||||
|
if((n = read(STDIN_FILENO, line, 256) < 0)) {
|
||||||
|
printf("read error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
alarm(0);
|
||||||
|
write(STDOUT_FILENO, line, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_alrm(int signo) {
|
||||||
|
longjmp(env_alrm, 1);
|
||||||
|
}
|
32
10/signal/recall.c
Normal file
32
10/signal/recall.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static void my_alarm(int signo) {
|
||||||
|
struct passwd *rootptr;
|
||||||
|
|
||||||
|
printf("in signal handler signo = %d\n", signo);
|
||||||
|
if ((rootptr = getpwnam("root")) == NULL) {
|
||||||
|
printf("getpwnam(root) error");
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct passwd *ptr;
|
||||||
|
|
||||||
|
signal(SIGALRM, my_alarm);
|
||||||
|
alarm(1);
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
if((ptr = getpwnam("eric")) == NULL)
|
||||||
|
printf("getpwnam(eric) error");
|
||||||
|
if(strcmp(ptr->pw_name, "eric") != 0) {
|
||||||
|
printf("return value corrupted, pw_name = %s\n", ptr->pw_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
10/signal/signal.c
Normal file
34
10/signal/signal.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include <sys/signal.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void sig_usr(int);
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
if(signal(SIGUSR1, sig_usr) == SIG_ERR) {
|
||||||
|
printf("can't catch SIGUSR1\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if(signal(SIGUSR2, sig_usr) == SIG_ERR) {
|
||||||
|
printf("can't catch SIGUSR2\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
pause();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_usr(int signo) {
|
||||||
|
if(signo == SIGUSR1) {
|
||||||
|
printf("SIGUSR1 received\n");
|
||||||
|
}
|
||||||
|
else if(signo == SIGUSR2) {
|
||||||
|
printf("SIGUSR2 recieved\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("error %d received", signo);
|
||||||
|
}
|
38
10/signal/sleep.c
Normal file
38
10/signal/sleep.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
static void sig_alrm(int signo) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int sleep(unsigned int seconds) {
|
||||||
|
struct sigaction newact, oldact;
|
||||||
|
sigset_t newmask, oldmask, suspmask;
|
||||||
|
unsigned int unslept;
|
||||||
|
|
||||||
|
newact.sa_handler = sig_alrm;
|
||||||
|
sigemptyset(&newact.sa_mask);
|
||||||
|
newact.sa_flags = 0;
|
||||||
|
sigaction(SIGALRM, &newact, &oldact);
|
||||||
|
|
||||||
|
sigemptyset(&newmask);
|
||||||
|
sigaddset(&newmask, SIGALRM);
|
||||||
|
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
|
||||||
|
|
||||||
|
alarm(seconds);
|
||||||
|
suspmask = oldmask;
|
||||||
|
|
||||||
|
sigdelset(&suspmask, SIGALRM);
|
||||||
|
sigsuspend(&suspmask);
|
||||||
|
unslept = alarm(0);
|
||||||
|
|
||||||
|
sigaction(SIGALRM, &oldact, NULL);
|
||||||
|
|
||||||
|
sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
||||||
|
return unslept;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return sleep(5);
|
||||||
|
}
|
48
10/signal/suspend.c
Normal file
48
10/signal/suspend.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void sig_int(int);
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
sigset_t newmask, oldmask, waitmask;
|
||||||
|
|
||||||
|
printf("program start\n");
|
||||||
|
|
||||||
|
if(signal(SIGINT, sig_int) == SIG_ERR) {
|
||||||
|
printf("signal(SIGINT) error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sigemptyset(&waitmask);
|
||||||
|
sigaddset(&waitmask, SIGUSR1);
|
||||||
|
sigemptyset(&newmask);
|
||||||
|
sigaddset(&newmask, SIGINT);
|
||||||
|
|
||||||
|
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
|
||||||
|
printf("SIG_BLOCK error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("in critical region\n");
|
||||||
|
|
||||||
|
if(sigsuspend(&waitmask) != -1) {
|
||||||
|
printf("sigsuspend error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("after return from sigsuspend\n");
|
||||||
|
|
||||||
|
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){
|
||||||
|
printf("SIG_SETMASK error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("program exit\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sig_int(int signo) {
|
||||||
|
printf("caught sigint = %d\n", signo);
|
||||||
|
}
|
59
10/signal/system.c
Normal file
59
10/signal/system.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int system(const char *cmdstring) {
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
struct sigaction ignore, saveintr, savequit;
|
||||||
|
sigset_t chldmask, savemask;
|
||||||
|
|
||||||
|
if (cmdstring == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ignore.sa_handler = SIG_IGN;
|
||||||
|
sigemptyset(&ignore.sa_mask);
|
||||||
|
ignore.sa_flags = 0;
|
||||||
|
if (sigaction(SIGINT, &ignore, &saveintr) < 0)
|
||||||
|
return -1;
|
||||||
|
if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
|
||||||
|
return -1;
|
||||||
|
sigemptyset(&chldmask);
|
||||||
|
sigaddset(&chldmask, SIGCHLD);
|
||||||
|
if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if((pid = fork()) < 0) {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
else if (pid == 0) {
|
||||||
|
sigaction(SIGINT, &saveintr, NULL);
|
||||||
|
sigaction(SIGQUIT, &savequit, NULL);
|
||||||
|
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
|
||||||
|
_exit(127);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (waitpid(pid, &status, 0) < 0)
|
||||||
|
if (errno != EINTR) {
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sigaction(SIGINT, &saveintr, NULL) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(sigaction(SIGQUIT, &savequit, NULL) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(sigprocmask(SIG_SETMASK, &savemask, NULL) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return system("ls .");
|
||||||
|
}
|
68
11/pthread/thread_clean.c
Normal file
68
11/pthread/thread_clean.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void cleanup(void *arg) {
|
||||||
|
printf("cleanup: %s\n", (char *) arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thr_fn1(void *arg) {
|
||||||
|
printf("thread 1 start\n");
|
||||||
|
pthread_cleanup_push(cleanup, (void *)"thread 1 first handler");
|
||||||
|
pthread_cleanup_push(cleanup, (void *)"thread 1 second handler");
|
||||||
|
|
||||||
|
printf("thread 1 push complete\n");
|
||||||
|
if(arg) {
|
||||||
|
return (void *)1;
|
||||||
|
}
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
return (void *)1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thr_fn2(void *arg) {
|
||||||
|
printf("thread 2 start\n");
|
||||||
|
pthread_cleanup_push(cleanup, (void *)"thread 2 first handler");
|
||||||
|
pthread_cleanup_push(cleanup, (void *)"thread 2 second handler");
|
||||||
|
|
||||||
|
printf("thread 2 push complete\n");
|
||||||
|
if(arg) {
|
||||||
|
pthread_exit((void *)2);
|
||||||
|
}
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
pthread_exit((void *)2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err;
|
||||||
|
pthread_t tid1, tid2;
|
||||||
|
void *tret;
|
||||||
|
|
||||||
|
err = pthread_create(&tid1, NULL, thr_fn1, (void *)1);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 1 create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pthread_create(&tid2, NULL, thr_fn2, (void *)1);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 2 create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pthread_join(tid1, &tret);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 1 join error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("thread 1 exit code %ld\n", (long)tret);
|
||||||
|
err = pthread_join(tid2, &tret);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 2 join error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("thread 2 exit code %ld\n", (long)tret);
|
||||||
|
return 0;
|
||||||
|
}
|
46
11/pthread/thread_exit.c
Normal file
46
11/pthread/thread_exit.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void *thr_fn1(void *arg) {
|
||||||
|
printf("thread 1 returning\n");
|
||||||
|
return (void *)1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thr_fn2(void *arg) {
|
||||||
|
printf("thread 2 exiting\n");
|
||||||
|
pthread_exit((void *)2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err;
|
||||||
|
pthread_t tid1, tid2;
|
||||||
|
void *tret;
|
||||||
|
|
||||||
|
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 1 create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pthread_create(&tid2, NULL, thr_fn2, NULL);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 2 create error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pthread_join(tid1, &tret);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 1 join error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("thread 1 exit code %ld\n", (long)tret);
|
||||||
|
err = pthread_join(tid2, &tret);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("thread 2 join error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printf("thread 2 exit code %ld\n", (long)tret);
|
||||||
|
return 0;
|
||||||
|
}
|
33
11/pthread/thread_id.c
Normal file
33
11/pthread/thread_id.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
pthread_t ntid;
|
||||||
|
|
||||||
|
void printids(const char *s) {
|
||||||
|
pid_t pid;
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
pid = getpid();
|
||||||
|
tid = pthread_self();
|
||||||
|
printf("%s pid %lu tid %lu (0x%lx)\n", s, (unsigned long) pid, (unsigned long) tid, (unsigned long) tid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thr_fn(void *arg) {
|
||||||
|
printids("new thread:");
|
||||||
|
return (void *)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = pthread_create(&ntid, NULL, thr_fn, NULL);
|
||||||
|
if(err != 0) {
|
||||||
|
printf("create thread error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
printids("main thread:");
|
||||||
|
sleep(1);
|
||||||
|
return 0;
|
||||||
|
}
|
36
11/pthread/thread_timedlock.c
Normal file
36
11/pthread/thread_timedlock.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err;
|
||||||
|
struct timespec tout;
|
||||||
|
struct tm *tmp;
|
||||||
|
char buf[64];
|
||||||
|
|
||||||
|
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
printf("mutex is locked\n");
|
||||||
|
clock_gettime(CLOCK_REALTIME, &tout);
|
||||||
|
tmp = localtime(&tout.tv_sec);
|
||||||
|
strftime(buf, sizeof(buf), "%r", tmp);
|
||||||
|
printf("current time is %s\n", buf);
|
||||||
|
|
||||||
|
tout.tv_sec += 10;
|
||||||
|
|
||||||
|
err = pthread_mutex_timedlock(&lock, &tout);
|
||||||
|
clock_gettime(CLOCK_REALTIME, &tout);
|
||||||
|
tmp = localtime(&tout.tv_sec);
|
||||||
|
strftime(buf, sizeof(buf), "%r", tmp);
|
||||||
|
|
||||||
|
printf("the time is now %s\n", buf);
|
||||||
|
if(err == 0)
|
||||||
|
printf("mutex locked again!n");
|
||||||
|
else
|
||||||
|
printf("can't lock mutex again: %s\n", strerror(err));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
80
12/attr/atfork.c
Normal file
80
12/attr/atfork.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
void prepare(void) {
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
printf("preparing locks...\n");
|
||||||
|
if((err = pthread_mutex_lock(&lock1) != 0)) {
|
||||||
|
printf("mutex lock error\n");
|
||||||
|
}
|
||||||
|
if((err = pthread_mutex_lock(&lock2)) != 0) {
|
||||||
|
printf("mutex lock error\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parent(void) {
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
printf("parent unlocking locks...\n");
|
||||||
|
if((err = pthread_mutex_unlock(&lock1)) != 0)
|
||||||
|
printf("mutex unlock error\n");
|
||||||
|
if((err = pthread_mutex_unlock(&lock2)) != 0)
|
||||||
|
printf("mutex unlock error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void child(void) {
|
||||||
|
|
||||||
|
int err;
|
||||||
|
|
||||||
|
printf("child unlocking locks...\n");
|
||||||
|
if((err = pthread_mutex_unlock(&lock1)) != 0)
|
||||||
|
printf("mutex unlock error\n");
|
||||||
|
if((err = pthread_mutex_unlock(&lock2)) != 0)
|
||||||
|
printf("mutex unlock error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void * thr_fn(void *arg) {
|
||||||
|
printf("thread started...\n");
|
||||||
|
pause();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err;
|
||||||
|
pid_t pid;
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
if((err = pthread_atfork(prepare, parent, child)) != 0) {
|
||||||
|
printf("install fork handlers error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if((err = pthread_create(&tid, NULL, thr_fn, 0)) != 0) {
|
||||||
|
printf("create thread error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
printf("parent about to fork...\n");
|
||||||
|
|
||||||
|
if((pid = fork()) < 0) {
|
||||||
|
printf("fork failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (pid == 0) {
|
||||||
|
printf("child return from fork\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("parent return from fork\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
30
12/attr/makethread.c
Normal file
30
12/attr/makethread.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int makethread(void *(*fn)(void *), void *arg) {
|
||||||
|
int err;
|
||||||
|
pthread_t tid;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
|
||||||
|
err = pthread_attr_init(&attr);
|
||||||
|
if(err != 0)
|
||||||
|
return err;
|
||||||
|
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
if(err == 0)
|
||||||
|
err = pthread_create(&tid, &attr, fn, arg);
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *td_fn(void *arg) {
|
||||||
|
printf("thread executing\n");
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int err = makethread(td_fn, NULL);
|
||||||
|
sleep(3);
|
||||||
|
return err;
|
||||||
|
}
|
46
9/processGroup/orphan.c
Normal file
46
9/processGroup/orphan.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
|
||||||
|
static void sig_hup(int singo) {
|
||||||
|
printf("SIGHUP received, pid = %ld, signo = %d\n", (long) getpid(), singo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pr_ids(char * name) {
|
||||||
|
printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",
|
||||||
|
name, (long)getpid(), (long)getppid(), (long)getpgrp(), (long)tcgetpgrp(STDIN_FILENO));
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char c;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
pr_ids("parent");
|
||||||
|
|
||||||
|
if((pid = fork()) < 0) {
|
||||||
|
printf("fork error\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else if (pid > 0) {
|
||||||
|
printf("parent sleep...\n");
|
||||||
|
sleep(3);
|
||||||
|
printf("parent exit.\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pr_ids("child");
|
||||||
|
signal(SIGHUP, sig_hup);
|
||||||
|
kill(getpid(), SIGTSTP);
|
||||||
|
pr_ids("child2");
|
||||||
|
if(read(STDIN_FILENO, &c, 1) != 1){
|
||||||
|
printf("read error %d on controlling TTY\n", errno);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user