多线程执行顺序诡异现象谈,你不知道的pthread_create

简介: 引文:学而时习之,不亦说乎。总是忙于具体项目,业务功能的实现;关于编程本身的技能都要有些生疏了,于是就选择了几个专题做了一次温习,重点放在了多线程和多进程上,跑了一个实例,居然有新的发现: (1)多个线程顺序创建的顺序=线程执行顺序吗? (2)多个线程顺序创建,回调函数执行顺序有规律吗? 示例: #include "apue.

引文:学而时习之,不亦说乎。总是忙于具体项目,业务功能的实现;关于编程本身的技能都要有些生疏了,于是就选择了几个专题做了一次温习,重点放在了多线程和多进程上,跑了一个实例,居然有新的发现:

(1)多个线程顺序创建的顺序=线程执行顺序吗?

(2)多个线程顺序创建,回调函数执行顺序有规律吗?

示例

#include "apue.h"
#include <pthread.h>

void *
thr_fn1(void *arg)
{
    printf("thread 1 returning\n");
    return((void *)1);
}

void *
thr_fn2(void *arg)
{
    printf("thread 2 exiting\n");
    pthread_exit((void *)2);
}

int
main(void)
{
    int            err;
    pthread_t    tid1, tid2;
    void        *tret;

    err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    if (err != 0)
        err_quit("can't create thread 1: %s\n", strerror(err));
    /*sleep(1);*/
    err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    if (err != 0)
        err_quit("can't create thread 2: %s\n", strerror(err));
    err = pthread_join(tid1, &tret);
    if (err != 0)
        err_quit("can't join with thread 1: %s\n", strerror(err));
    printf("thread 1 exit code %d\n", (int)tret);
    err = pthread_join(tid2, &tret);
    if (err != 0)
        err_quit("can't join with thread 2: %s\n", strerror(err));
    printf("thread 2 exit code %d\n", (int)tret);
    exit(0);
}

输出

thread 2 exiting
thread 1 returning
thread 1 exit code 1
thread 2 exit code 2

讨论

  看到这个顺序是否有点意外,从多线程实现的机制来讲,这个顺序是没问题的,创建的过程不等于执行的过程,各种教科书都会这么告诉我们。可是我想知道的是,创建的顺序是否和执行的顺序有关系呢?还是用数据说话吧,我执行了10次,每次的输出顺序都是如此。这个引起了我的兴趣。线程2为何每次都是优先于线程1执行呢?按照cup顺序工作的原理,线程1应该先得到时间片才对啊,至少线程1和线程2应该具有同等的执行顺序才对。为何每次的结果都是线程2限制性?却是线程1先完成呢?纠结探索中,有条件的园友可以自己测试一下,看看是否有同样的问题呢。

疑问1:同时创建线程是否线程2优先于1呢?-----单台机器实测来看貌似如此。

疑问2:顺序创建时间差增大,执行顺序会如何?我在线程1创建后做了一个sleep(1),结果:

thread 1 returning
thread 1 exit code 1
thread 2 exiting
thread 2 exit code 2

疑问3:顺序创建线程,线程2的执行顺序为何优于线程1?探索中...!求答案!

环境

vmware8.0 + windows xp + REHL6.3


作者:张子良
出处:http://www.cnblogs.com/hadoopdev
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

相关文章
|
数据采集 Python
等一等,你的多线程可别再乱 join 了。
等一等,你的多线程可别再乱 join 了。
90 0
|
Java 调度
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
55 1
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
|
调度
解决程序堵塞的优化方法(一)
解决程序堵塞的优化方法(一)
284 0
解决程序堵塞的优化方法(一)
解决程序堵塞的优化方法(二)
解决程序堵塞的优化方法(二)
182 0
解决程序堵塞的优化方法(二)
|
Java
【Java多线程】写一个死锁的例子
【Java多线程】写一个死锁的例子
114 0
|
调度
【多线程:wait/notify详解】原理及错误用法(虚假唤醒等)
【多线程:wait/notify详解】原理及错误用法(虚假唤醒等)
201 0
|
安全
【多线程:转账例子】探究两个对象对应两个线程如何加锁
【多线程:转账例子】探究两个对象对应两个线程如何加锁
320 0
|
安全 Java
Java线程之join方法&死锁&Timer
线程锁 锁定的是对象 1.放置在方法的结构上 public synchronized void test(){ 好多代码 执行代码 好多代码 } 对象.test(); 对象被某一个访问他的线程锁定 2.放置在方法(构造 块)的内部(看起来是包含着一堆代码) public void test(){ 好多代码 synchronized(对象){ 执行代码 } 好多代码 } 3.线程相关的一些方法 sleep(); run(); start(); setPriority();--------
208 0
|
Java
一个线程中断的Bug:明明中断了线程,却为何不起作用呢?
一个线程中断的Bug:当我们在调用Java对象的wait()方法或者线程的sleep()方法时,需要捕获并处理InterruptedException异常。如果我们对InterruptedException异常处理不当,则会发生我们意想不到的后果!今天,我们就以一个案例的形式,来为大家详细介绍下为何中断执行的线程不起作用。
420 0
一个线程中断的Bug:明明中断了线程,却为何不起作用呢?
|
Linux
Linux系统编程-(pthread)线程的使用案例(分离属性、清理函数等)
这篇文章介绍Linux下线程的创建与基本使用案例,主要是案例代码为主;相关的函数详细介绍在上篇文章里已经介绍过了。
215 0

相关实验场景

更多