简单明了搞清楚到底什么是线程(linux下,附实验代码)

简单介绍下文章结构:

1.前言

2.实验代码

3.实验结果

4.根据实验结果对代码的分析

1.前言

        实验目的:理解、掌握什么是线程

        实验原理:main主线程创建两个子线程,三个线程共享一块内存(指的是变量i),同时两个子线程拥有独立的上下文,不断打印共享内存的值和两个子线程各自拥有的变量(self value),通过观察打印出的值去理解什么是线程,线程的特点、内存使用、共享代码段等等一堆令我初学时懵b的东西。

2.实验代码

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef struct pthread_data_s
{
	int test_pthread_id;
	pthread_t test_pthread;
	int *in_value;
	int self_value;
}pthread_data_t;

void* printf_hello_world(void* tid);

int main(void)
{
	pthread_data_t test_pthread_1;
	pthread_data_t test_pthread_2;
	int test_pthread_ret = 0;
	int test_pthread1_ret = 0;
	int status, i = 10;
	memset(&test_pthread_1, 0, sizeof(pthread_data_t));
	memset(&test_pthread_2, 0, sizeof(pthread_data_t));
	test_pthread_1.in_value = &i;
	test_pthread_2.in_value = &i;
	test_pthread_1.self_value = 15;
	test_pthread_2.self_value = 5;
	printf("Main here. Creating thread %d\n", i);
	status = pthread_create(&(test_pthread_1.test_pthread), NULL, printf_hello_world, &test_pthread_1);
	if (status == 0)
		printf("thread created success, tp1:test_pthread_id:%d\n",test_pthread_1.test_pthread_id);

	status = pthread_create(&(test_pthread_2.test_pthread), NULL, printf_hello_world, &test_pthread_2);
	if (status == 0)	
		printf("thread created success, tp2:test_pthread_id:%d\n",test_pthread_2.test_pthread_id);
	int pthread_main_self_id = 0;
	sleep(2);
	printf("thread1: handle_id:%d, id:%d, self_value:%d.\n",(int)test_pthread_1.test_pthread, test_pthread_1.test_pthread_id, test_pthread_1.self_value);
	printf("thread2: handle_id:%d, id:%d, self_value:%d.\n",(int)test_pthread_2.test_pthread, test_pthread_2.test_pthread_id, test_pthread_2.self_value);
	//pthread_join(test_pthread, NULL);
	//pthread_main_self_id = pthread_self();
	
	while (1)
	{
		sleep(1);
		if( i >= 0)
			printf("global share value:%d.\n",i);
		else
			break;
	}
	status = pthread_join(test_pthread_1.test_pthread,NULL);
	if(status == 0)
		printf("pthread1 exit success.\n");
	else 
		printf("pthread1 exit error.\n");
	status = pthread_join(test_pthread_2.test_pthread,NULL);
	if(status == 0)
		printf("pthread2 exit success.\n");
	else 
		printf("pthread2 exit error.\n");	
	exit(0);
}

void* printf_hello_world(void* tid)
{
	pthread_data_t *pthread_data_tmp = NULL;
	pthread_data_tmp = (pthread_data_t *)tid; 
	pthread_data_tmp->test_pthread_id = pthread_self();
	printf("Son %d thread here Hello world %d. \n", pthread_data_tmp->test_pthread_id, *(pthread_data_tmp->in_value));
	while(1)
	{
		sleep(1);
		if (*(pthread_data_tmp->in_value) <= 0 && pthread_data_tmp->self_value <=0)
			break;
		printf("Son:%d:\n",pthread_data_tmp->test_pthread_id);
		if (*(pthread_data_tmp->in_value) >= 0)
			printf("	global share value:%d.\n",(*(pthread_data_tmp->in_value))--);
		if (pthread_data_tmp->self_value >= 0)
			printf("	self value:%d.\n",pthread_data_tmp->self_value--);
	}
	pthread_exit(NULL);
}

3.实验结果

这里直接贴linux打印截图

简单说一下整个流程,

(1)主函数创建两个子线程,并且为两个子线程传递了参数,主要关注的参数为i:主线程创建的共享内存;self_value两个子线程各自拥有的变量,该变量已经初始化。

(2)主线程轮询打印全局共享内存i

        与此同时

  两个子线程同时对共享变量i进行-1操作,对自己拥有的变量self_value同样进行-1操作,

(3)当两个子线程将共享内存的值减到0并且将他们各自变量self_value减到0时,结束自己的线程,如果没有减到0,则继续执行。

(4)观察打印结果,可以发现,子线程1和子线程2可以一起修改共享内存i,同时各自会修改各自的值。主线程也可以访问共享内存。

(5)直到最后两个子线程完成自己任务,线程结束,主线程也结束了。

4.根据实验结果对代码的分析

(1)主线程中,我使用了pthread_exit(0)进行结束(代码中应该是pthread_exit(),忘记改了),并没有使用return。原因是:如果不使用pthread_join()函数让主线程阻塞,return会直接结束该进程(因为是main函数,在这里相当于exit,会直接退出进程)对应的子线程也会全部结束,如果使用pthread_exit,只会结束当前主线程,并不会结束还没执行完任务的两个线程。这就好比,下班时间规定是六点半,但是你实际下班时间是八点,那么你的主线程使用的就是pthread_exit,干完活的走,没干完活的继续干。使用return的话,相当于六点半到点之后,公司直接让所有人下班回家并关闭大门。

(2)创建线程时使用的句柄:pthread_t类型的参数,创建之后的值是线程的id,与在创建的子线程中使用pthread_self拿到的值是一个值。

(3)还有几个函数未解释,后面再说,return了

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值