Example of fork and mutex lock process in Linux multithreading

Example of fork and mutex lock process in Linux multithreading

Question:

We have such a problem: create a child process in a multi-threaded program and let子線程and子進程acquire a lock of a global variable, the output child thread gets the lock, then unlocks it, the child process gets the lock, and then unlocks it;

1. First attempt

Code:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/wait.h>

pthread_mutex_t mutex;

void* fun(void* arg)
{
	pthread_mutex_lock(&mutex);	
	printf("fun get lock\n");
	sleep(3);

	pthread_mutex_unlock(&mutex);
	printf("fun unlock\n");
}
int main()
{
	pthread_mutex_init(&mutex, NULL);
	pthread_t id;
	pthread_create(&id, NULL, fun, NULL);
	
	sleep(1);
	pid_t pid = fork();
	if(pid == -1)
	{
		perror("fork err");
		return -1;
	} 

	if(pid == 0)
	{
		pthread_mutex_lock(&mutex);	
		printf("child get lock\n");
		sleep(3);
		
		pthread_mutex_unlock(&mutex);
		printf("child unlock\n");
		exit(0);
	}
	
	wait(NULL);

	pthread_mutex_destroy(&mutex);
	printf("main over\n");
	return 0;
}

Conjecture results:

Sort out your thoughts:

Create a global lock and initialize it
The main thread creates a child thread to acquire the lock. The main thread sleeps for one second, and the child thread gets the lock and locks it.
The child thread sleeps for 3 seconds, outputs unlock fun, and the child thread exits
The main thread starts forking, the child process gets the lock, and outputs child lock
Child process unlock output child unlock
The main thread of the parent process waits for the child process to exit, and finally destroys the lock and outputs main over
So… get straight to the correct code! ! !

2. Rational Analysis

Unfortunately, the answer is wrong! ! !

我們先來康康運行結果:正常輸出了子線程的內容,但是。。。。卡住了?沒錯阻塞了。。

insert image description here

Analyze again:

block? ? Could it be that the child process is blocked when acquiring the lock? Or is the parent process blocked waiting for the child process?
In other words: both places are blocked, the child process is blocked when acquiring the lock, causing the parent process to be blocked.
Verify it! !

insert image description here

So the program is blocked in two places. The child process is blocked when acquiring the lock, causing the parent process to be blocked.

3. Problem Solving

實際上,我們子線程在獲取這把鎖并加鎖后睡眠3秒,主線程睡眠1秒,在主線程1秒睡眠結束后,開始執行fork,此時的子線程還未解鎖正處于睡眠狀態,fork過程中,會直接復制父進程的所有資源(**包括這把鎖、鎖的狀態**),沒錯

就是有兩把鎖。此時子線程進行了加鎖的狀態,所以子線程復制的鎖也是加鎖狀態。所以子線程會正常退出,而子進程會因為拿到加鎖的鎖而阻塞,父進程wait因為子進程阻塞而阻塞;

(1) Using pthread_join()

Use pthread_join() before fork. Before the child thread ends, the main thread will be blocked and wait for the child thread to end before forking. At this time, the lock obtained by the child process is unlocked.

Code:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/wait.h>

pthread_mutex_t mutex;

void* fun(void* arg)
{
	pthread_mutex_lock(&mutex);	
	printf("fun get lock\n");
	sleep(3);

	pthread_mutex_unlock(&mutex);
	printf("fun unlock\n");
}
int main()
{
	pthread_mutex_init(&mutex, NULL);
	pthread_t id;
	pthread_create(&id, NULL, fun, NULL);
	pthread_join(id, NULL);
	
	sleep(1);

	pid_t pid = fork();
	if(pid == -1)
	{
		perror("fork err");
		return -1;
	} 

	if(pid == 0)
	{
		pthread_mutex_lock(&mutex);	
		printf("child get lock\n");
		sleep(3);

		pthread_mutex_unlock(&mutex);
		printf("child unlock\n");
		exit(0);
	}
	
	wait(NULL);

	pthread_mutex_destroy(&mutex);
	printf("main over\n");
	return 0;
}

result:

insert image description here

(2) Use phread_atfork() to register a pre-fork judgment

Header file: pthread.h

int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));

prepare: This function is called before fork is executed

parent: The parent process calls this function after fork is executed

child: The child process calls this function after fork is executed

Return value: 0 if successful, error code if failed

Code:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/wait.h>

pthread_mutex_t mutex;

void prepare_fun(void)
{
	pthread_mutex_lock(&mutex);
}

void parent_fun(void)
{
	pthread_mutex_unlock(&mutex);
}

void child_fun()
{
	pthread_mutex_unlock(&mutex);
}

void* fun(void* arg)
{
	pthread_mutex_lock(&mutex);	
	printf("fun get lock\n");
	sleep(3);

	pthread_mutex_unlock(&mutex);
	printf("fun unlock\n");
}

int main()
{
	
	pthread_mutex_init(&mutex, NULL);
	pthread_t id;
	pthread_atfork(prepare_fun, parent_fun, child_fun);
	pthread_create(&id, NULL, fun, NULL);
	
	sleep(1);

	pid_t pid = fork();
	if(pid == -1)
	{
		perror("fork err");
		return -1;
	} 

	if(pid == 0)
	{
		pthread_mutex_lock(&mutex);	
		printf("child get lock\n");
		sleep(3);

		pthread_mutex_unlock(&mutex);
		printf("child unlock\n");
		exit(0);
	}
	
	wait(NULL);

	pthread_mutex_destroy(&mutex);
	printf("main over\n");
	return 0;
}

result:

insert image description here

This is the end of this article about the fork and mutex process examples in Linux multithreading. For more relevant Linux multithreading fork and mutex content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of Python garbage collection mechanism
  • Python language development garbage collection mechanism principle tutorial
  • Analysis of the principle of Python garbage collection mechanism
  • How is Python garbage collection implemented?
  • Introduction to fork in multithreading under Linux
  • Python Garbage Collection and Linux Fork

<<:  Implementation of CSS linear gradient concave rectangle transition effect

>>:  How to get the dynamic number of remaining words in textarea

Recommend

Nginx external network access intranet site configuration operation

background: The site is separated from the front ...

MySQL 8.0 New Features - Introduction to Check Constraints

Table of contents Preface Check Constraints Creat...

Gradient slide effect implemented by CSS3

Achieve results Code html <div class="css...

VMware kali virtual machine environment configuration method

1|0 Compile the kernel (1) Run the uname -r comma...

Users need to know why

When I was in the securities company, because the ...

MySQL query specifies that the field is not a number and comma sql

Core SQL statements MySQL query statement that do...

MySQL stored functions detailed introduction

Table of contents 1. Create a stored function 2. ...

How to build a complete samba server in Linux (centos version)

Preface smb is the name of a protocol that can be...

10 skills that make front-end developers worth millions

The skills that front-end developers need to mast...

Steps to install MySQL 5.7 in binary mode and optimize the system under Linux

This article mainly introduces the installation/st...

Three common ways to embed CSS in HTML documents

The following three methods are commonly used to d...

MySQL permission control details analysis

Table of contents 1. Global level 2. Database lev...

MySQL account password modification method (summary)

Preface: In the daily use of the database, it is ...

MySQL 8.0.18 installation and configuration graphic tutorial

Learning objectives: Learn to use Windows system ...