8.1 补充练习(一)

hello.c

        关键词:pthread_exit()

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

#define NUM_THREADS	5

void *PrintHello(void *threadid)
{
  long tid;
  tid = (long)threadid;
  sleep(2);
  printf("Hello World! It's me, thread #%ld!\n", tid);
  pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
  pthread_t threads[NUM_THREADS];
  int rc;
  long t;
  for(t=0;t<NUM_THREADS;t++){
    printf("In main: creating thread %ld\n", t);
    rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
    if (rc){
      printf("ERROR; return code from pthread_create() is %d\n", rc);
      exit(-1);
    }
  }

  /* Last thing that main() should do */
  pthread_exit(NULL);
  printf("return\n");
  return 0;
}

        这里主线程创建了5个子线程,子线程中会在休眠2S后打印传入的线程id;代码的输出打印如下。

In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
In main: creating thread 3
In main: creating thread 4
Hello World! It's me, thread #1!
Hello World! It's me, thread #0!
Hello World! It's me, thread #2!
Hello World! It's me, thread #3!
Hello World! It's me, thread #4!

        如果我们将main()中的pthread_exit()屏蔽,运行后的输出如下。

In main: creating thread 0
In main: creating thread 1
In main: creating thread 2
In main: creating thread 3
In main: creating thread 4

        说明了如下信息:

  • 主线程创建子线程后,需要使用一些机制确保子线程执行完毕后进程再结束退出;pthread_exit()是其中的一种方法。
  • 主线程调用pthread_exit()后,主线程会直接退出(因为之后的printf()调用并没有打印出来信息);但进程会在各个子线程执行完毕后再退出。
  • 主线程直接return后会导致整个进程直接退出,使得子线程尚未执行printf()就被销毁。

hello_args

关键词:参数传递

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

#define NUM_THREADS	5

void *PrintHello(void *threadid)
{
  long tid;
  tid = *(long*)threadid;
  sleep(2);
  printf("Hello World! It's me, thread #%ld!\n", tid);
  pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
  pthread_t threads[NUM_THREADS];
  int rc;
  long t;
  for(t=0;t<NUM_THREADS;t++){
    printf("In main: creating thread %ld\n", t);
    rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&t);
    if (rc){
      printf("ERROR; return code from pthread_create() is %d\n", rc);
      exit(-1);
    }
  }

  /* Last thing that main() should do */
  pthread_exit(NULL);
  printf("return\n");
  return 0;
}

        这是一个错误的线程参数传递调用示例,相比上面的hello.c这段代码只是将之前的值传递((void*)t)改为了指针传递((void*)&t),同时子线程接受参数时也做了相应的修改,但它是错误的,为何?

        回答:hello.c中使用值传递的形式,t当时的值会产生拷贝副本保存在子线程对应的堆栈内,t之后的变化不会影响子线程的使用;而hello_args.c中传给子线程的是t的指针,t之后的变化会影响到访问它的子线程。

        如何在仍然使用指针传递的方法下解决该问题?避免各个线程访问共同的内存即可;譬如将t声明为数组,每个子线程访问独立的数组元素。使用指针传递参数更加自由,但需要注意由此可能带来的调用bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mega_Li

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

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

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

打赏作者

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

抵扣说明:

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

余额充值