printf 地址_[Linux编程]pthread_create()参数传递注意问题(参数传地址问题)

情形一:ptread_create()中传递值

typdedef struct{   char ch *;  int aa;} STR;void *func(void *arg){  int b = (int)arg;  printf("%d", b);  STR *str = (STR *)malloc(sizeof(STR));  str->ch = "hello";  str->aa = 100;  pthread_exit((void *)str);}main(){  pthread_t tid[2];  for (i = 0; i < 2; i++)    pthread_create(&tid[i], NULL, ftn, (void *)i);  for (i = 0; i < n; i++) //回收每个子线程        {      STR *re; //re位于主控线程的栈空间,但是re本身的值为子线程传给它的值。      pthread_join(tid[i], (void **)&re);    }}

注意问题:

1、如下图所示,此处是(void*)i,而不是(void*)&i,因为线程创建的时候,不能传递一个变化的参数,此处,i由0变成1。

8aa9bde1c006797c4db28e9d56d938b2.png

2、如下图所示,1条中传递的值,线程函数中转换的时候,直接转int,转换是与phtread_create的保持一致。取的是这个地址值i.

 608e2450c75165a2d894082dbd2c626b.png

3、 如下图所示,传递的参数和返回的参数并不是同一个

eee1f060edb45a62809d953f94e72bf0.png

4、 如下图所示,因为返回值是指针,所以函数中的指针需是动态创建的。

c256748d95632c077e43b791dad34fb1.png

  情形二:ptread_create()中使用动态指针传递

void *func(void *arg){  int value = *(int *)arg;  printf("%d\n", value);}int main(void){  pthread_t pid[2];  int ret;  for (int i = 0; i < 6; ++i)  {    int *p = malloc(sizeof(int));    *p = i;    if ((ret = pthread_create(&pid[i], NULL, thread, (void *)p)) != 0)    {      fprintf(stderr, "pthread_create:%s\n", strerror(ret));      exit(1);    }  }}

1、如下图所示,用动态指针传递,也不会发生问题

d8337f971cce8571abc245e5f9da0302.png

 情形三:错误示范,参数传递指针

void *func(void *arg){  int value = *(int *)arg;  printf("%d\n", value);}int main(void){  pthread_t pid[2];  int ret;  for (int i = 0; i < 6; ++i)  {    if ((ret = pthread_create(&pid[i], NULL, thread, (void *)&i)) != 0)    {      fprintf(stderr, "pthread_create:%s\n", strerror(ret));      exit(1);    }  }}

 输出结果:

236666

1、如下图所示,正常的思维是,传递i的地址,但是运行会出现错误,原因是线程的创建需要时间,

187fed997fac55951e2af4e30f945893.png

 for循环中,执行了6个phread_create()函数后,i变为了6,因为线程中调用thread函数时需要一定的时间,此时再去到&i地址去取i值时,i都变为6了,所以会出现上述的情况。

所以,情况一和情况二的可以避免这种情况的发生。

总结:不能在线程创建过程中,改变传递的参数,避免该问题产生的方法是传递值或者使用动态申请内存的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值