[color="#660099"]3.当持有某个信号灯锁的进程没有释放它就终止时,内核并不给该信号灯解锁.
#include stdio.h>
#include stdlib.h>
#include unistd.h>
#include pthread.h>
#include fcntl.h>
#include errno.h>
#include sys/stat.h>
#include semaphore.h>
#define SEM_MODE (S_IRUSR | S_IWUSR)
int main(int argc, char *argv[])
{
int i;
int ret_val;
int value;
sem_t* psem;
psem = sem_open("test3",O_CREAT,SEM_MODE,1);
if(psem==SEM_FAILED) {
printf("sem error\n");
printf("%s\n",strerror(errno));
}
printf("Begin to create process...\n");
sem_getvalue(psem,&value);
printf("%d\n",value);
if (fork() == 0 ) {//son
printf("son process\n");
sem_wait(psem);
printf("son in the critical region\n");
sem_post(psem);
sem_close(psem);
exit(1);
}
printf("fathre process\n");
sem_wait(psem);
printf("father in the critical region\n");
sem_post(psem);
printf("Now, the main process returns.\n");
sem_close(psem);
sem_unlink("test3");
return 0;
}
$ gcc test.c -lrt
$ ./a.out
Begin to create process...
1
son process
son in the critical region
fathre process
father in the critical region
Now, the main process returns.
可以看到上面的程序执行很好,
但是如果在子进程中把exit提前至sem_post之前
if (fork() == 0 ) {//son
printf("son process\n");
sem_wait(psem);
printf("son in the critical region\n");
[color="#ff0000"]exit(1);
sem_post(psem);
sem_close(psem);
}
$ gcc test.c -lrt
$ ./a.out
Begin to create process...
1
son process
son in the critical region
fathre process
在这里一直等待下去
可见当子进程sem_wait->exit后,父进程会一直在sem_wait处等待.
4.有名信号灯既可用于线程间的同步,又可以用于进程间的同步.
5.posix有名信号灯是通过内核持续的,一个进程创建一个信号灯,另外的进程可以通过该信号灯的外部名(创建信号灯使用的文件名)来访问它。
posix基于内存的信号灯的持续性却是不定的,
如果基于内存的信号灯是由单个进程内的各个线程共享的,那么该信号灯就是随进程持续的,当该进程终止时它也会消失。
如果某个基于内存的信号灯是在不同进程间同步的,该信号灯必须存放在共享内存区中,这时只要该共享内存区存在,该信号灯就存在。
6.基于内存的信号灯应用于进程很麻烦,而有名信号灯却很方便,
基于内存的信号灯比较适合应用于一个进程的多个线程。
reference: Posix多线程编程学习笔记(三)—信号灯 Linux 系统编程 ->进程通讯 -> 信号灯