fork() 和 锁
其实标题中“继承”这个词用得非常不好
因为锁这种东西有两个方面:
- 内存中的数据结构
- 内存中的数据结构的可见性
由于fork会复制一份堆栈数据,所以锁也肯定是复制了一份,所以锁在新的进程中也是可见的,但是新的进程中看到的只是锁的复制品,和主进程中创建的锁无关
具体参考:
https://blog.csdn.net/lyh__521/article/details/45921515
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
pthread_mutex_t mutex;
int main() {
pthread_mutex_init(&mutex,NULL);
pthread_mutex_lock(&mutex);
int pid = fork();
if(pid<0) {
pthread_join(pid,NULL);
pthread_mutex_destroy(&mutex);
return 1;
} else if(pid == 0) {
printf("I am in the child,want to get the lock\n");
pthread_mutex_lock(&mutex);
printf("I am running here,oop...\n");
pthread_mutex_unlock(&mutex);
printf("I unlocked\n");
exit(0);
} else {
sleep(3);
pthread_mutex_unlock(&mutex);
printf("unlocked\n");
wait(NULL);
}
pthread_join(pid,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
fork() 和 信号量
信号量也是同样的。
在面试中回答过很多次,信号量可以用于进程间通信后,误以为匿名信号量可以直接用在有父子关系的进程间通信。
具体参考:https://blog.csdn.net/aprilweet/article/details/53098824
#include <stdio.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
sem_t * test = NULL;
void* child(void *arg)
{//Child
sleep(1);
printf("Child: sem_post ing\n");
if(sem_post(test) < 0)
{
printf("Child: sem_post fialed\n");
return NULL;
}
if(sem_destroy(test) < 0)
{
printf("Child: sem_destroy failed\n");
}
return NULL;
}
void *parent(void *arg)
{//Parent
while(1)
{
printf("Parent: sem_wait ing\n");
if(sem_wait(test) < 0)
{
printf("Parent: sem_wait failed\n");
continue;
}
printf("Parent: waked up by Child\n");
}
if(sem_destroy(test) < 0)
{
printf("Parent: sem_destroy failed\n");
}
}
int main(void)
{
__pid_t pid;
test = malloc(sizeof(sem_t));
if(test == NULL)
{
printf("malloc failed\n");
return 1;
}
if(sem_init(test, 1, 0) < 0)
{
printf("sem_init failed\n");
return 1;
}
pid=fork();
if(pid==0)
{
child(NULL);
}
else if(pid>0)
{
parent(NULL);
}
else
{
perror("fork");
}
return 0;
}
Parent: sem_wait ing
Child: sem_post ing
可以看到 parent 开在等待信号量的那段代码,
而这里我们把 fork 换为 thread_create 即可正常执行,
int main(void)
{
__pid_t pid;
test = malloc(sizeof(sem_t));
if(test == NULL)
{
printf("malloc failed\n");
return 1;
}
if(sem_init(test, 1, 0) < 0)
{
printf("sem_init failed\n");
return 1;
}
pthread_t id;
pthread_create(&id,NULL,child,NULL);
parent(NULL);
return 0;
}
Parent: sem_wait ing
Child: sem_post ing
Parent: waked up by Child
Parent: sem_wait ing