创建线程时的几个陷阱

原创 2006年05月25日 20:54:00

创建线程时的几个陷阱

 

前几天帮同事查一个多线程的BUG,不到十秒钟我就找到了问题的根源。N年前我曾犯过类似的错误,呵,今天仍然有人在重复。这些问题都比较典型,把它们写出来,供新手参考吧。

 

l         用临时变量作为线程参数的问题。

#include <stdio.h>

#include <pthread.h>

#include <assert.h>

 

void* start_routine(void* param)

{

    char* str = (char*)param;

 

    printf("%s:%s/n", __func__, str);

 

    return NULL;

}

 

pthread_t create_test_thread()

{

    pthread_t id = 0;

    char str[] = "it is ok!";

 

    pthread_create(&id, NULL, start_routine, str);

 

    return id;

}

 

int main(int argc, char* argv[])

{

    void* ret = NULL;

    pthread_t id = create_test_thread();

 

    pthread_join(id, &ret);

 

    return 0;

}

 

分析:由于新线程和当前线程是并发的,谁先谁后是无法预测的。可 create_test_thread 已经执行完成,str已经被释放了,新线程才拿到这参数,此时它的内容已经无法确定了,自然打印出的字符串是随机的。

 

l         线程参数共享的问题。

#include <stdio.h>

#include <pthread.h>

#include <assert.h>

 

void* start_routine(void* param)

{

    int index = *(int*)param;

 

    printf("%s:%d/n", __func__, index);

 

    return NULL;

}

 

#define THREADS_NR 10

void create_test_threads()

{

    int i = 0;

    void* ret = NULL;

 

    pthread_t ids[THREADS_NR] = {0};

 

    for(i = 0; i < THREADS_NR; i++)

    {

        pthread_create(ids + i, NULL, start_routine, &i);

    }

 

    for(i = 0; i < THREADS_NR; i++)

    {

        pthread_join(ids[i], &ret);

    }

 

    return ;

}

 

int main(int argc, char* argv[])

{

    create_test_threads();

 

    return 0;

}

 

 

分析:由于新线程和当前线程是并发的,谁先谁后是无法预测的。i在不断变化,所以新线程拿到的参数值是无法预知的,自然打印出的字符串也是随机的。

 

l         虚假并发。

#include <stdio.h>

#include <pthread.h>

#include <assert.h>

 

void* start_routine(void* param)

{

    int index = *(int*)param;

 

    printf("%s:%d/n", __func__, index);

 

    return NULL;

}

 

#define THREADS_NR 10

void create_test_threads()

{

    int i = 0;

    void* ret = NULL;

 

    pthread_t ids[THREADS_NR] = {0};

 

    for(i = 0; i < THREADS_NR; i++)

    {

        pthread_create(ids + i, NULL, start_routine, &i);

        pthread_join(ids[i], &ret);

    }

 

    return ;

}

 

int main(int argc, char* argv[])

{

    create_test_threads();

 

    return 0;

}

 

分析:因为pthread_join会阻塞直到线程退出,所以这些线程实际上是串行执行的,一个退出了,才创建下一个。当年一个同事写了一个多线程的测试程序,就是这样写的,结果没有测试出一个潜伏的问题,直到产品运行时,这个问题才暴露出来。

版权声明:本文为博主原创文章,未经博主允许不得转载。

创建线程时的几个陷阱

 前几天帮同事查一个多线程的BUG,不到十秒钟我就找到了问题的根源。N年前我曾犯过类似的错误,呵,今天仍然有人在重复。这些问题都比较典型,把它们写出来,供新手参考吧。 l         用临时变量作...
  • dubble
  • dubble
  • 2007年03月07日 12:07
  • 272

java创建线程的四种方式

java创建线程的三种方式 1. 继承Thread类创建线程类 2. 通过Runable接口创建线程类 3. 通过Callable和FutureTask创建线程     a. 创建Callab...
  • u012973218
  • u012973218
  • 2016年04月29日 10:51
  • 2991

创建线程的几种方法及比较

1、通过继承Thread类创建线程 (1).首先定义一个类去继承Thread父类,重写父类中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。 (2).直接创建一个ThreadTes...
  • u012470138
  • u012470138
  • 2016年11月21日 10:17
  • 2583

并发编程学习总结(二) : 详解 线程的6种不同状态

(一) 线程状态: 我们先讨论一下线程的几种状态: java中Thrad.State总共有6中状态: (1)New (新创建) (2)Runnable (可运行) (3)Bolcked (被阻塞) (...
  • u011784767
  • u011784767
  • 2016年05月06日 10:44
  • 2625

操作系统—陷阱、中断、异常

在操作系统中,陷阱,中断和异常是常见的术语,它们贯穿操作系统学习的始终,这篇文章主要区分它们之间的不同。 陷阱 计算机有两种运行模式:用户态, 内核态。 其中操作系统运行在内核态,在内核态中,操作...
  • qq_30866297
  • qq_30866297
  • 2016年07月27日 16:20
  • 645

子序列的和(注意溢出问题)

输入两个正整数n 分析:还是for循环累加。 本题陷阱在于n比较大时,n*n会溢出,所以 1/n^2 应该用 1/n/n 而不是 1/(n*n)。...
  • leafinsnowfield
  • leafinsnowfield
  • 2014年10月08日 22:00
  • 406

扇形陷阱和断层陷阱(即当一个实体有多个一对多关系时)

设计关联是数据库设计中必经的一个环节。在实体建立之后,我们开始考虑实体与实体之间的相互关系,从而建立关联。然而在实际操作中,关联的设计常常会进入误区。下面介绍两种比较著名的扇形陷阱(FanTraps)...
  • gao8658
  • gao8658
  • 2011年08月26日 21:10
  • 1897

中断和陷阱的区别(转载)

外部中断,就是我们通常所说的中断(interrupt)。对于执行的系统来说,这种中断发生完全是"异步"的,根本无法预测到此类中断会在什么时候发生。因此,CPU(或者软件)对于此类外部中断完全是"被动"...
  • fantasyagain
  • fantasyagain
  • 2011年01月06日 09:59
  • 4670

Java中的陷阱

Java中创建对象的常规方式有如下5种:           1. 通过new调用构造器创建Java对象;         2. 通过Class对象的newInstance()方法调用构造器创建对象;...
  • geloin
  • geloin
  • 2013年11月06日 14:05
  • 2292

SNMP陷阱(SNMP Trap)

SNMP陷阱(SNMP Trap)是由一个SNMP代理发送的信息给管理员,其使一个代理通知管理站的重要事件,通过一个未被请求的SNMP信息。在SNMP自陷的通知后面的观点是这样的:如果一个管理员是负责...
  • gxj022
  • gxj022
  • 2009年09月11日 08:51
  • 1876
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:创建线程时的几个陷阱
举报原因:
原因补充:

(最多只允许输入30个字)