• 关于线程


    code from <UNIX 高级编程第二版>

    一个进程中的所有线程都可以访问该进程的组成部件,如文件描述符和内存。

    pthread_t的数据类型表示线程ID

    func1.    pthread_t pthread_self(void)

    返回线程ID

    func2.    int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg)      创建成功则返回0,否则返回错误编号

    restrict,C语言中的一种类型限定符,用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容

    第一个参数为指向线程标识符的指针

    第二个参数用来设置线程属性

    第三个参数是创建线程起始的运行函数

    第四个参数是运行函数的参数

    (void*)无类型指针,也可以认为是任意类型指针,其他任意类型的指针如int*等都可以转化成(void*)类型指针

    单个线程的三种退出方式,在不终止整个进程的情况下停止它的控制流

    (1)线程只是从启动例程中返回,返回值是线程的退出码

    (2)线程可以被同一进程中的其他线程取消

    (3)线程调用pthread_exit;

    func3: void pthread_exit(void *rual_ptr)

    参数rual_ptr与传给启动例程的单个参数类似。进程中的其他线程可以通过调用pthread_join这个函数访问到这个指针

    func4: int pthread _join(phread_t thread,void  ** rual_ptr )     若成功则返回0,否则返回错误编号

    调用线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。

    获取已终止线程的退出码:

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

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

    void* thr_fn2(void* arg)
    {
        printf("thread 2 exit ");
        pthread_exit((void*)2);
    }

    int main()
    {
        pthread_t ntid1,ntid2;
        int err;
        void * tret;
        err = pthread_create(&ntid1,NULL,thr_fn1,NULL);
        if(err != 0)
        {
            printf("can not create thread 1 ");
        }
        err = pthread_create(&ntid2,NULL,thr_fn2,NULL);
        if(err != 0)
        {
            printf("can not create thread 2 ");
        }
        err = pthread_join(ntid1,&tret);
        if(err != 0)
        {
            printf("can not join thread 1");
        }
        printf("thread 1 exit code is %d ",(int)tret);

            err = pthread_join(ntid2,&tret);
        if(err != 0)
        {
            printf("can not join thread 2");
        }
        printf("thread 2 exit code is %d ",(int)tret);
        exit(0);
    }

    func5:       itn phread_cancel(pthread_t tid)    返回值为0则成功 

    线程可以通过调用上述函数来请求取消同一进程中的其他线程。但只是请求,不一定响应。

    互斥量与线程同步

    互斥量的本质是为了实现原子操作

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

    int tickets = 10;
    pthread_mutex_t lock;

    void* thread(void*arg)
    {
        while(tickets > 0)
        {
            //pthread_mutex_lock(&lock);
            if(tickets > 0)
            {
                usleep (100*1000);
                tickets --;
                printf("%s sold tickets %d ",arg,tickets);
            }
            //pthread_mutex_unlock(&lock);
        }
        return (void*)1;
    }


    int main()
    {
        pthread_t tid1,tid2;
        pthread_mutex_init(&lock,NULL);
        int ret;
        char*name = "the first :";
        void* tret;
        ret = pthread_create(&tid1,NULL,thread,(void*)name);
        if(ret != 0)
        {
            printf("creat thread1 failed! ");
        }
        name = "the second :";
        ret = pthread_create(&tid2,NULL,thread,(void*)name);
        if(ret != 0)
        {
            printf("creat thread2 failed! ");
        }
        ret = pthread_join(tid1,&tret);
        if(ret != 0)
        {
            printf("can not join thread 1");
        }

            ret = pthread_join(tid2,&tret);
        if(ret != 0)
        {
            printf("can not join thread 2");
        }
        exit(0);
    }

    未加锁时结果如下:

    加锁的结果:

    未加锁时虽然ticket已经减到0了,但另一线程几乎同时走到了sleep的部分,于是再自减1得到-1的结果,加锁后则不会出现这样的情况,另一线程必须等到锁被unlock,才能继续走下去。

  • 相关阅读:
    springboot1.x+dubbo案例
    dubbo相关的博文
    druid监控配置
    Tomcat启动报错整理
    Hibernate @OneToMany等注解设置查询过滤条件等
    异常处理
    复杂的xml转化为java实体
    简单Java类与XML之间的转换
    mysql errno 150
    JdbcTemplate进行查询
  • 原文地址:https://www.cnblogs.com/doulcl/p/10461497.html
Copyright © 2020-2023  润新知