C语言-多线程-线程执行函数、互斥锁\线程函数malloc与free

1、线程执行函数的参数:

pthread_create(线程地址,线程属性(NULL),线程执行哪个函数的名字,将主线程中的参数的地址给到线程执行函数作为参数。)

如:在主线程中,给出线程执行函数所需要的参数为int a,假设a的地址为0x12345;

创建线程,pthread_create(&th1, NULL, myfunc, &a

线程执行函数:void* myfunc(void* agrs){         };&a = agrs,args的值就是0x12345,传入到线程执行函数的参数就是主线程中给出的参数的地址,是一个。因此,在线程执行函数如果要修改主线程中给出的参数,也可以通过不设置返回值,用指针来实现。比如:void* myfunc(void* agrs){    int* p = (int*)agrs, *p  = 6  };那么主线程中的a变量的值已经变为6。

2、多个线程函数是否会对操作的变量有冲突,加锁等:

如果多个线程操作的变量是同一个全局变量,那么需要加锁。如果是对各自建立的局部变量进行操作,那么在多个线程执行函数内部是互不影响的。但是如果是malloc,注意对内存的释放。

3、假共享:如果多个线程函数所操作的对象在内存中距离特别近的时候,比如紧挨着,实际上会造成假共享,影响程序运行速度,这个具体去查阅一下吧。

4、pthread_create(&th1, NULL, myfunc, &a

th1:线程名称  myfunc:这个线程要执行的线程执行函数   &a:将主线程中给出的参数地址给到myfunc去做处理。

5、pthread_join与pthread_exit

pthread_exit:用于线程执行函数中,用于返回线程执行函数的返回值。返回的是返回值的指针:

pthread_exit( (void*)myfunc_result );

pthread_join:用在主线程中,用于等待线程结束并接收线程执行函数返回的返回值的地址。

void* threcv_result: 在主线程中创建一个指针变量接收线程执行函数返回值的地址。

pthread_join(th[i],&threcv_result); 实际上: threcv_result = myfunc_result=线程执行函数中开辟的动态内存空间,虽然pthread_join的参数是threcv_result的地址,实际上执行的是根据threcv_result的地址将threcv_result的值设置为 pthread_exit中的存储线程执行函数返回值的地址。

pthread_join相当于将线程执行函数返回值的地址带回到主线程中。

下面这个代码有助于理解pthread_join是如何把线程执行函数的返回值带回到主调函数中的:

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

void* func(void* agrs)
{
    int* a = (int*)calloc(3,4);

    

    printf("the value of a is %p\n\n",a);

    pthread_exit((void*)a);
    
    return;
}

int main(void)
{
    pthread_t th;
    pthread_create(&th, NULL, func, NULL);
    void* b;
    pthread_join(th, &b);

    printf("the value of b is %p\n\n",b);

    return 0;

}

打印结果为:a和b的值是一样的,都指向了在线程执行函数中动态分配的那块内存。pthread_join相当于带回了在线程执行函数中动态分配的内存。

6、pthread_exit:执行pthread_exit后,线程执行函数中定义的局部变量所在的栈区被释放。因此,不能把线程执行函数中局部变量的地址作为pthread_exit的参数,pthread_exit的参数应该是在静态区或者堆区等不会随线程执行函数销毁的区域。

参见:https://blog.csdn.net/modi000/article/details/104684582/

void* mufunc(void* p)
{
	int a = 9;
	
	int* q = &a;
	
	
//	printf("q value is %p = \n",q);
	
	pthread_exit((void*) q);
	
	return NULL;
	
}

int main(void)
{
	
	pthread_t th;
	
	int a = 5;
	
	printf("a address is %p\n", &a);
	
	void* p;
	
	pthread_create(&th, NULL, mufunc, &a);
	
	pthread_join(th, &p);
	
	printf("p = %p\n", p);
	
	printf("%d\n", *(int*)p);//运行程序,这里无法输出,因为该地址已经被释放。
	
}

从下面这个程序中,也可以看到pthread_exit和pthread_exit的入参出参,其实都是同样的地址。

void* mufunc(void* p)
{
	int* q = (int*)p;
	
 	*q = 8;
	
	printf("q value is %p = \n",q);
	
	pthread_exit((void*) q);
	
	return NULL;
	
}

int main(void)
{
	
	pthread_t th;
	
	int a = 5;
	
	printf("a address is %p\n", &a);
	
	void* p;
	
	pthread_create(&th, NULL, mufunc, &a);
	
	pthread_join(th, &p);
	
	printf("p = %p\n", p);
	
	printf("%d\n", *(int*)p);//可以正常输出,因为变量a是定义在主线程中的,这个地址不会受mufunc中的pthread_exit的执行而被释放。
	
}

当不同的指针存储同样的地址时,这些指针都可以对那个地址上的变量进行操作。

7、多线程的malloc与free:在线程执行函数中malloc的指针,可以在主线程中free。在不同线程中,函数malloc的区域是独立的,不是共用的。而且每个线程的pthread_join返回的是自己线程的malloc指针,free即可。

8、可以多用printf打印看看实际情况。

9、多根据数据结构想一下,画一下图。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哇123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值