linux线程详解(一)

一.为什么要使用线程

在没有线程的情况下,进程是程序执行流的最小单位,程序的执行可以被分割成很多进程来实现,但对于有些细微的过程,如果组织一个进程来执行,会比较浪费资源,因为,我

们都知道每个进程的创建都是要开辟整块的进程空间,代码段,数据段,堆,栈等,而线程就是一个很好的选择,线程有如下有点:

线程间的共享数据比进程间共享简单的多

线程的创建更加快速

线程使用占用更少的资源

但线程也有自己的缺点:

使用线程编程,我们必须确认自己的线程安全(多线程常常因为不当的共享数据访问而出问题)

一个线程中的bug很可能使所有线程都挂掉

多个线程需要竞争其所在进程地址空间

二.线程概述

一个进程可以有多个线程,它们虽然分开执行,但是它们共享全局变量,包括:初始数据,未初始数据,堆,但每个线程都有自己单独的栈(调用函数必须用到)

线程的内存分配图


三.linux线程API

1.线程数据类型

Data type
Description
pthread_t
Thread identifier
pthread_mutex_t
Mutex
pthread_mutexattr_t
Mutex attributes object
pthread_cond_t
Condition variable
pthread_condattr_t
Condition variable attributes object
pthread_key_t
Key for thread-specific data
pthread_once_t
One-time initialization control context
pthread_attr_t
Thread attributes object

2.线程和errno

在linux中,errno被设定为一个全局的整型,很明显对于线程这种方法并不适用,因为多个线程会竞争使用errno,而结果就是errno中存储的错误值未必能够对应到出现错误的线程。所以在linux将errno设定为一系列可以根据返回值区分线程的宏函数。

3.线程函数的返回值

和普通函数不同,线程函数返回0代表成功,负数代表失败

4.线程的创建

#include <pthread.h>

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

thread指向一个pthread_t类型的buf,其中存放着线程的标识符,start指向线程的调用函数,arg是传给调用函数的参数,attr指向一个设定线程的属性结构体

5.线程的结束

线程的结束方式:

线程函数返回

线程调用pthread_eixt()

线程通过pthread_cancel()被取消

任何线程调用exit(),或者主线程return,都会让所有线程结束

include <pthread.h>
void pthread_exit(void *retval);

6.线程ID

include <pthread.h>
pthread_t pthread_self(void);

每个线程通过其ID被唯一标识,这个ID可以通过pthread_self()函数活得

include <pthread.h>

int pthread_equal(pthread_t t1, pthread_t t2);

pthread_equal函数可以被用来检测两个两个线程ID是否相同

7.等待线程结束

include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

pthread_join函数可以用来等待指定ID线程结束,如果该线程已经结束,则该函数立马返回,如果retval为非空指针,那么它将复制一份线程函数的返回值

8.隔离一个线程

默认情况下,每个线程都是可以被等待结束的,有些情况下我们不需要关注一个线程的返回状态,只想在它结束之后立马收回资源,这个时候我们可以隔离(detach)该线程

#include <pthread.h>

int pthread_detach(pthread_t thread);

一个线程被隔离之后,便无法被等待结束,而且一旦被隔离,便无法被恢复

-------------------------------------------------------------------------------------------------------------------------

线程测试代码,这段代码根据用户输入参数个数为创建线程个数,对应为线程名

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


void * threadFunc(void * arg)
{
        printf("This is thread %s, it's ID is %lu!\n",(char *)arg,pthread_self());
}

int main(int argc, char ** argv)
{
        pthread_t * pt;
        int i, s;

        if(1 == argc )
                perror("Wrong arguments!");
        else
        {
                pt = calloc(argc -1, sizeof(pthread_t));
                for(i=1;i<argc;i++)
                {
                        s = pthread_create(&pt[i-1], NULL, threadFunc, argv[i]);
                        if(0!=s)
                                perror("thread create failed!");
                        printf("thread No%d has created!\n",i);
                }
                for(i=1;i<argc;i++)
                {
                        s = pthread_join(pt[i-1], NULL);
                        if(0!=s)
                                perror("thread join failed!");
                        printf("thread No%d has terminated!\n",i);
                }
        }
        return 0;
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值