UNIX网络编程之线程浅析

什么是线程:线程是一个进程内部的控制系列;线程是CPU调度的基本单位

线程的优点:

(1) 通过为每种事件类型的处理分配单独的线程,能够简化处理异步时间的代码。
(2) 多个线程可以自动共享相同的存储地址空间和文件描述符。
(3) 有些问题可以通过将其分解从而改善整个程序的吞吐量。
(4) 交互的程序可以通过使用多线程实现相应时间的改善,多线程可以把程序中处理用户输入输出的部分与其它部分分开。

线程的缺点:

在多线程程序里,因为时间分配的细微偏差或者因为共享了不该共享的变量可能会造成很大的不良影响。因此调试一个多线程程序比调试一个单线程的程序困难很多。

线程的结构:

线程包含了表示进程内执行环境必须的信息,其包括进程中标示线程的线程ID,调度优先级,线程的私有数据,一组寄存器值, 栈,策略,信号屏蔽子及errno变量。调用进程的所有信息对该线程都是共享的,其中包括可执行程序文本,程序的全局内存和堆内存,栈以及文件描述符。

线程的标识:

每个进程都有ID,所以每个线程也有ID。 但是进程ID在整个系统中是唯一的,线程ID不是唯一的,因为线程ID只在其所属的进程环境中有效。

线程的相关函数:
pthread_self 得到线程的id号
函数原型:`

   pthread_t pthread_self(void);

`

只要是想得到某个线程的线程ID号,就可使用该函数,例如:

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

using namespace std;

int main()
{
    printf("this pthread's id = %u\n", pthread_self());
    return 0;
}



//执行结果如下:
[root@localhost mine]# g++ pthread.cpp -o pthread -lpthread
[root@localhost mine]# ls
pthread  pthread.cpp  test  test.cpp
[root@localhost mine]# ./pthread 
this pthread's id = 3220752192 [root@localhost mine]# 

pthread_create 线程创建函数
函数原型如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

参数thread是线程id;
attr是线程属性;attr== NULL时表示默认属性,即非分离,非绑定,缺省1M的堆栈,与父进程同样级别的优先级;
第三个参数是一个参数为void*类型,返回值为void*类型的函数指针;
第四个参数arg是第三个参数的参数;
注意:若是第三个参数函数指针的参数个数不止一个,那就要将那些参数写入一个结构体中,然后将结构体的地址传给arg就可以啦^_^

该函数的使用示例如下:

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

using namespace std;

void *thread_func(void *arg)
{
    for(int i = 0; i < 10; ++i){
        printf("this is child pthread.\n");
    }
}

int main()
{
    pthread_t tid;   //线程id

    sleep(1);
    pthread_create(&tid, NULL, thread_func, NULL);
    for(int i = 0; i < 10; ++i)
    {
        printf("this is Main pthread.\n");
    }
    return 0;
}


//未加sleep之前的输出结果:
[root@localhost mine]# g++ pthread.cpp -o pthread -lpthread
[root@localhost mine]# ./pthread 
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
[root@localhost mine]# ./pthread 
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
[root@localhost mine]# 




//加了sleep之后的输出结果:
[root@localhost mine]# ./pthread 
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
[root@localhost mine]# ./pthread 
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
[root@localhost mine]# 

pthread_exit 线程终止函数
函数原型如下:

void pthread_exit(void *retval)

该函数的作用就是终止调用线程,参数retval是线程退出时退出码所保存的地方,这个退出码用于pthread_join的retval参数
使用如下:

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

using namespace std;

void *thread_func(void *arg)
{
    for(int i = 0; i < 10; ++i){
        printf("this is child pthread.\n");

        if(i == 4){  //子线程执行5次就结束
            const char* retval = "child normal quit."; //每次和pthread_exit函数一起出现
            pthread_exit((void *)retval);
        }
    }

}

int main()
{
    pthread_t tid;   //线程id

    pthread_create(&tid, NULL, thread_func, NULL);

    for(int i = 0; i < 10; ++i)
    {
        printf("this is Main pthread.\n");
    }

    char *retval;
    pthread_join(tid, (void **)&retval);
    printf("child thread exit code:> %s\n", retval);
    return 0;
}


//执行结果如下:
[root@localhost mine]# ./pthread 
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
child thread exit code:> child normal quit.
[root@localhost mine]# ./pthread 
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is child pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
this is Main pthread.
child thread exit code:> child normal quit.
[root@localhost mine]# 

pthread_join 线程等待函数
函数原型如下:

int pthread_join(pthread_t thread, void **retval)

第一个参数是线程id,第二个参数是函数pthread_exit的参数
示例如下:

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

using namespace std;

void *thread_func(void *arg)
{
    for(int i = 0; i < 10; ++i){
        printf("this is child pthread.\n");

        if(i == 4){  //子线程执行5次就结束
            const char* retval = "child normal quit.";
            pthread_exit((void *)retval);
        }
    }

}

int main()
{
    pthread_t tid;   //线程id

    pthread_create(&tid, NULL, thread_func, NULL);

    for(int i = 0; i < 10; ++i)
    {
        printf("this is Main pthread.\n");
    }

    char *retval;
    pthread_join(tid, (void **)&retval);  //retval不为NULL时表示接收pthread_exit中的字符串,用以判断子线程是否正常终止,若retval为NULL则表示不接收pthread_exit中的retval字符串
    printf("child thread exit code:> %s\n", retval);
    return 0;
}

以上只是简单的函数解说,关于线程的属性,其比起这些函数来说比较复杂,会在下一篇博客中介绍^^ ^^ ^_^

你可能感兴趣的:(多线程,线程,网络编程,线程的标记和结构,线程的优缺点)