Linux下子进程如何继承互斥锁 (linux子进程继承互斥)

在多进程编程中,互斥锁是一种重要的工具,用于协调多个进程或线程对共享资源的访问。然而,在Linux下创建子进程时,需要考虑如何继承互斥锁。

需要理解互斥锁的概念和使用方法。互斥锁是一种同步原语,用于保护共享资源免受并发访问的风险。当多个进程或线程需要访问同一共享资源时,互斥锁可以确保在同一时间只有一个进程或线程可以访问该共享资源。

在Linux下创建子进程时,子进程会复制父进程的所有资源,包括互斥锁。但是,复制并不意味着子进程可以直接使用父进程的互斥锁。相反,子进程需要重新初始化互斥锁,并确保只有它自己可以使用它。否则,子进程和父进程之间的竞争会导致互斥锁失效,而共享资源会受到破坏。

为了继承父进程的互斥锁,子进程需要注意以下几点:

1. 锁的类型

互斥锁可以分为进程锁和线程锁。进程锁是利用文件锁实现的,可以在不同进程之间共享。线程锁只能在同一进程中使用。如果父进程使用的是线程锁,子进程需要更改为进程锁,以便在不同进程享。

2. 锁的名字

在初始化锁时,需要为锁指定一个唯一的名字,以便在不同进程之间共享。如果父进程没有指定锁的名字,那么子进程必须使用同样的近似策略来为锁命名。

3. 锁的属性

在初始化锁时,需要根据要保护的共享资源来设置锁的属性。例如,如果需要保护的资源是在内存中的,则需要将锁的属性设置为PTHREAD_PROCESS_SHARED。这样,子进程才能够共享该锁并保护该资源。

因此,在继承父进程的互斥锁时,子进程需要进行以下步骤:

1. 获取锁的类型

可以使用pthread_mutexattr_t结构体中的pshared成员来判断锁的类型(线程锁或进程锁)。

2. 获取锁的名字

如果父进程指定了锁的名字,则子进程可以通过shm_open()或sem_open()等函数来打开该锁。否则,子进程需要使用同样的近似策略来为锁命名。

3. 获取锁的属性

可以使用pthread_mutexattr_t结构体中的flags成员来获取锁的属性。

4. 初始化锁

通过调用pthread_mutex_init()函数来初始化锁。如果子进程需要更改锁类型、名字或属性,则必须传递相应的参数。

5. 销毁锁

在子进程中使用完锁后,必须调用pthread_mutex_destroy()函数来销毁锁以释放资源。

在实际编程中,可以采用如下代码来继承父进程的互斥锁:

#include

#include

#include

#include

#include

#include

#include

#define SHM_SIZE 4096

void PthreadMutexInit(pthread_mutex_t *mutex)

{

int res;

pthread_mutexattr_t mutexAttr;

res = pthread_mutexattr_init(&mutexAttr);

if (res != 0){

perror(“pthread_mutexattr_init() error.”);

exit(1);

}

res = pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);

if (res != 0){

perror(“pthread_mutexattr_setpshared() error.”);

exit(1);

}

res = pthread_mutexattr_setprotocol(&mutexAttr, PTHREAD_PRIO_INHERIT);

if (res != 0){

perror(“pthread_mutexattr_setprotocol() error.”);

exit(1);

}

res = pthread_mutex_init(mutex, &mutexAttr);

if (res != 0){

perror(“pthread_mutex_init() error.”);

exit(1);

}

}

int mn()

{

int shmid;

char *addr;

pid_t pid;

pthread_mutex_t *mutex;

shmid = shm_open(“/myshm”, O_RDWR | O_CREAT, 0777);

if (shmid == -1){

perror(“shm_open() error.”);

exit(1);

}

if (ftruncate(shmid, SHM_SIZE) == -1){

perror(“ftruncate() error.”);

exit(1);

}

addr = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);

if (addr == MAP_FLED){

perror(“mmap() error.”);

exit(1);

}

mutex = (pthread_mutex_t *) addr;

PthreadMutexInit(mutex);

pid = fork();

if (pid

perror(“fork() error.”);

exit(1);

}

else if (pid == 0){

printf(“Child process.\n”);

mutex = (pthread_mutex_t *) addr;

pthread_mutex_lock(mutex);

printf(“Child process locked.\n”);

sleep(5);

pthread_mutex_unlock(mutex);

printf(“Child process unlocked.\n”);

exit(0);

}

else{

printf(“Parent process.\n”);

pthread_mutex_lock(mutex);

printf(“Parent process locked.\n”);

sleep(5);

pthread_mutex_unlock(mutex);

printf(“Parent process unlocked.\n”);

wt(NULL);

pthread_mutex_destroy(mutex);

munmap(addr, SHM_SIZE);

shm_unlink(“/myshm”);

exit(0);

}

}

在上述代码中,我们使用了共享内存来实现父进程和子进程之间的通信。通过共享内存,父进程和子进程都可以访问同一把互斥锁。同时,我们在初始化互斥锁时使用PTHREAD_PROCESS_SHARED属性,以保证其可以在不同进程间共享。在父进程和子进程使用完互斥锁后,必须分别调用pthread_mutex_destroy()和munmap()函数来销毁锁和释放共享内存。

相关问题拓展阅读:

  • linux中A进程调用system执行shell,启动B进程然后kill A进程,这个时候再启动A进程时,报错端口被占用了
  • Linux Shell脚本的执行过程

linux中A进程调用system执行shell,启动B进程然后kill A进程,这个时候再启动A进程时,报错端口被占用了

进程A使用system调用执行一个命令,会生成一个子进程C来执行,当启动进程Bkill了A进程后,进程A打开的文件描述符会由子进程继承,所以A原本占用的端口(其实纤宴 就是文件描述符)就被子进程C占用了。

正确的方法应该是先停止子进程C,然后再让进程A退出。或者在进程A的代码中,使用unix编程接口,不要让子进谈让程继承继承文件描述符(这个比较复杂,需要自己看unix编程毁侍银的书)

Linux Shell脚本的执行过程

用户登录时,将会取得一个

bash

,这个

bash

在系统中有一个全局唯一的ID,也就是进程的ID,使用命令

ps -ef

并配合

grep

来查看进程ID。

ps -ef|grep bash

,此命令还能查看进程对应的父进程ID,系统中所有进程的祖先进程都是INIT进程戚隐(进程ID=1),它是更先启动运行的。

回到

bash

进程,也就是我们的命令行界面,进程的执行都神圆有其附属的执行环境,环境变量就属于其中之一。并且环境变量是可以完全被子进程继承的,也就是说,子进程可以使用父进程的环境变量,但是不能使用父进程的自定义变量。

简而言之:

子进高瞎厅程继承父进程的环境变量,不继承父进程的自定义变量。

shell脚本有4种执行方式,不同的执行方式可能导致结果不一致

四种方式的执行结果如下:

关于linux子进程继承互斥的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《Linux下子进程如何继承互斥锁 (linux子进程继承互斥)》
文章链接:https://zhuji.vsping.com/32617.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。