Linux线程介绍及函数操作

线程特点:
    1.通常线程指的是共享相同地址空间的多个任务
    2.使用多线程的好处
        大大提高了任务切换的效率
        避免了额外的TLB和cache的刷新

线程共享资源:
    一个进程中的多个线程共享以下资源:
        1.可执行的指令
        2.静态数据
        3.进程中打开的文件描述符
        4.当前工作目录
        5.用户ID
        6.用户组ID

线程私有资源:
    1.线程ID(TID)
    2.pc(程序计数器)和相关寄存器
    3.堆栈
    4.错误号(errno)
    5.优先级
    6.执行状态和属性

Linux线程库:
    ·pthread线程库中提供以下操作
        创建线程    回收线程    结束线程
    ·同步和互斥机制
        信号量    互斥锁

使用线程库编译时
    gcc -o test test.c -lpthread

线程创建——pthread_create:
    #include <pthread.h>
    int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*routine)(void*),void *arg);

    成功时返回0,失败返回错误码
    thread线程对象
    attr线程属性,NULL代表默认属性
    routine线程执行的函数
    arg传递给routine的参数,不需要传参就NULL

线程回收——pthread_join
    #include <pthread.h>
    int pthread_join(pthread_t thread,void **retval);

    成功时返回0,失败返回错误码
    thread要回收的线程对象
    调用线程阻塞直到thread结束
    *retval接收线程thread的返回值

线程结束——pthread_exit
    #include <pthread.h>
    void pthread_exit(void *retval);

    结束当前线程
    retval可被其他线程通过pthread_join获取
    线程私有资源被释放    

示例:

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

        char message[32] = "hello world";

        void *thread_func(void *arg);

        int main(int argc, char const *argv[])
        {
            pthread_t a_thread;
            void *result;

            if(pthread_create(&a_thread,NULL,thread_func,NULL) != 0)
            {
                printf("fail to pthread_create");
                exit(-1);//表示程序异常退出。
            }
            pthread_join(a_thread,&result);
            printf("message is %s\n", message);
            return 0;
        }

        void *thread_func(void *arg)
        {
            sleep(1);
            strcpy(message,"marked by thread");
            pthread_exit("thank you fo waiting for me");
        }


线程间通信:
    ·线程共享同一进程的地址空间
    优点:
        线程间通信容易  通过全局变量交换数据
    缺点:
        多个线程访问共享数据时需要同步或互斥机制

信号量:
    信号量代表某一类资源,其值表示系统中该资源的数量

    信号量是一个受保护的变量,只能通过三种操作来访问
        1.初始化 
        2.P操作(申请资源)
        3.V操作(释放资源)

    posix中定义了两类信号量
        无名信号量    有名信号量

    信号量初始化:

#include <semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int val);

        成功时返回0.失败返回EOF
        sem指向要初始化的信号量
        pashared:0 线程间 1 进程间
        val 信号量初始值 0:没有资源 大于0 有资源

    P / V操作:
        #include <semaphore.h>
        int sem_wait(sem_t *sem);    P操作
        int sem_post(sem_t *sem);   V操作
        成功返回0,失败返回EOF
        sem指向要操作的信号量对象

互斥:
    ·临界资源:
        一次只允许一个任务(进程,线程)访问的共享资源
    ·临界区:
        访问临界区的代码
    ·互斥机制:
        mutex互斥锁
        访问临界资源前申请锁,访问完后释放锁

    互斥锁初始化:
        #include <pthread.h>
        int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);

        成功返回0,失败返回错误码
        mutex指向要初始化的互斥锁对象
        attr 互斥锁属性,NULL表述缺省属性

    申请锁:

#include <pthread.h>    
int pthread_mutex_lock(pthread_mutex_t *mutex);

    成功返回0,失败返回错误码
    mutex指向要初始化的互斥锁对象
    如果无法获得锁,任务阻塞

    释放锁:

 #include <pthead.h>
 int pthread_mutex_unlock(pthread_mutex_t *mutex);

        成功返回0,失败返回错误码
        mutex 指向要初始化的互斥锁对象
        执行完临界区要及时释放锁    示例:
        互斥锁_LOCK_宏定义
        编译时:
        gcc -o test test.c -D_LOCK_
        //-D 表示加入宏定义

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

        unsigned int count,value1,value2;
        pthread_mutex_t lock;

        void *function(void *arg);

        int main(int argc, char const *argv[])
        {
            pthread_t a_thread;

            if(pthread_mutex_init(&lock,NULL) != 0)
            {
                printf("fail to pthread_mutex_init \n");
                exit(-1);
            }
            if (pthread_create(&a_thread,NULL,function,NULL) != 0)
            {
                printf("fail to pthread_create");
                exit(-1);//表示程序异常退出。
            }
            while(1)
            {
                count++;
                #ifdef _LOCK_
                    pthread_mutex_lock(&lock);
                #endif
                    value1 = count;
                    value2 = count;

                #ifdef _LOCK_
                    pthread_mutex_unlock(&lock);
                #endif
            }
            return 0;
        }

        void *function(void *arg)
        {
            while(1)
            {
                #ifdef _LOCK_
                    pthread_mutex_lock(&lock);
                #endif
                    if(value1 != value2)
                    {
                        printf("value1 = %u ,value2 = %u \n",value1.value2);
                        usleep(100000);
                    }
                #ifdef _LOCK_
                    pthread_mutex_unlock(&lock);
                #endif

            }
            return  NULL;
        }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

点灯师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值