OS note04 -- process, thread

本文详细探讨了在Linux环境下,进程与线程的创建机制,包括fork()系统调用和pthread库函数的使用,展示了如何通过代码实例来观察进程与线程的行为,以及它们之间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <unistd.h>
int main()
{
	printf("start from main (pid:%d)\n", (int)getpid());
	int rc;
	rc = fork();
	if( rc == 0 )
		printf("fork() 1, (pid:%d)\n", rc);
	else if( rc > 0 )
		printf("parent of [fork() 1, (pid:%d)], (pid:%d)\n", rc, (int)getpid());
	printf("back to (pid:%d)\n", (int)getpid());
	rc = fork();
	if( rc == 0 )
		printf("fork() 2, (pid:%d)\n", rc);
	else if( rc > 0 )
		printf("parent of [fork() 2, (pid:%d)], (pid:%d)\n", rc, (int)getpid());
	printf("back to (pid:%d)\n", (int)getpid());
	rc = fork();
	if( rc == 0 )
		printf("fork() 3, (pid:%d)\n", rc);
	else if( rc > 0 )
		printf("parent of [fork() 3, (pid:%d)], (pid:%d)\n", rc, (int)getpid());
	printf("back to (pid:%d)\n", (int)getpid());
	return 0;
} 

The main function altogether will call fork() 3 times. Each time a fork() system call is invoked, a new process is created, since the child process is almost an exact copy of its parent, the child process will continue to run the code, for example if the child process is created by the first fork(), it will run the code below this call, that is the second and the third fork().

 

references:

https://eli.thegreenplace.net/2018/launching-linux-threads-and-processes-with-clone/

For processes, there's a bit of copying to be done when fork() is invoked, which costs time, due to the lack of CLONE_VM (see https://blog.youkuaiyun.com/MoMo_flamboyant/article/details/83182113).
Linux has an important optimization by using COW (Copy On Write) pages. The child's memory pages are initially mapped to the same pages shared by the parent, and only when we modify them the copy happens. But still, the page tables still have to be copied.
On the other hand, this overhead is not applied the thread, since threads inside a process are sharing address space - using same page tables and mappings.

 

LINE C

CHILD: value = 5

LINE P

PARENT: value = 0

 

For a set of user threads created in a user process, there is a set of corresponding Light Weight Processes(LWPs) in the kernel.

 

test.c

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
struct message {
	int i, j;
}; 
void *hello(struct message *arg)
{
	printf("child thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	printf("%d %d\n", arg->i, arg->j);
	pthread_exit(0);
}
int main(int argc, char *argv[])
{
	printf("main process (pid=%d)\n", (int)getpid());
	printf("main/parent thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	struct message test;
	pthread_t thread_id;
	test.i = 10; test.j = 20;
	pthread_create(&thread_id, NULL, hello(&test), NULL);
	printf("********\n");
	pthread_join(thread_id, NULL);
	printf("********\n");
	return 0;
}

 

test2.c

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
void *runner1(void *param)
{
	printf("child thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	pthread_exit(0);
}
void *runner2(void *param)
{
	printf("child thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	pthread_exit(0);
}
int main()
{
	printf("main process (pid=%d)\n", (int)getpid());
	printf("main thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	pid_t cpid = fork();
	if( cpid == 0 ) {	// child process
		printf("child process (pid=%d)\n", cpid);
		printf("parent thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
		pthread_t tid1;
		pthread_create(&tid1,NULL,runner1,NULL);
		pthread_join(tid1,NULL);
	}
	else if( cpid > 0 ) {	// parent process
		printf("parent process (pid=%d) of process (pid=%d)\n", (int)getpid(), cpid);
		printf("parent thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
		pthread_t tid2;
		pthread_create(&tid2,NULL,runner2,NULL);
		pthread_join(tid2,NULL);
	}
	return 0;
}

 

test3.c

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
void *runner(void *param)
{
	printf("child thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	pthread_exit(0);
}
int main()
{
	printf("main process (pid=%d)\n", (int)getpid());
	printf("main thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
	pid_t pid1 = fork();	//1
	if( pid1 == 0 ) {
		printf("child process (pid1=%d)\n", pid1);
		pid_t pid = fork();	//*
		if( pid == 0 ) {
			printf("child process (pid*=%d)\n", pid);
		}
		else if( pid > 0 ) {
			printf("parent process (pid=%d) of process (pid*=%d)\n", (int)getpid(), pid);
		}
		printf("parent thread: in process (pid=%d), tid = %lu, pid = %ld\n", (int)getpid(), pthread_self(), syscall(SYS_gettid));
		pthread_t tid;
		pthread_create(&tid,NULL,runner,NULL);
		pthread_join(tid,NULL);
	}
	else if( pid1 > 0 ) {
		printf("parent process (pid=%d) of process (pid1=%d)\n", (int)getpid(), pid1);
	}
	pid_t pid2 = fork();	//2
	if( pid2 == 0 ) {
		printf("child process (pid2=%d)\n", pid2);
	}
	else if( pid2 > 0 ) {
		printf("parent process (pid=%d) of process (pid2=%d)\n", (int)getpid(), pid2);
	}
	return 0;
}

6 unique processes are created.

8 unique threads are created.

 

 

注意:

pthread库不是Linux系统默认的库,连接时需要使用静态库libpthread.a,所以在线程函数在编译时,需要连接库函数,
gcc xxx.c -o xxx -lpthread

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值