linux系统编程笔记——线程(1) 线程基本概念

线程

线程的概念

会话是用来承载进程组的,里面可以有一个或多个进程,一个线程中可以有一个或多个线程
线程的本质就是一个正在运行的函数 ,线程没有主次之分(main函数 也只是一个main线程),多个线程之间共享内存,

posix线程是一套标准,而不是实现,我们主要讨论这套标准

  • 线程标识 pthead_t 类型不确定
  • pthread_equal()
  • pthread_self()

线程的一生

线程的创建

  • pthread_create()
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

static void *func(void *p){
    puts("thread is working");
    return NULL;
}

int main()
{
    printf("Begin\n");
    pthread_t ptid;

    int err = pthread_create(&ptid,NULL,func,NULL);
    if (err){
        fprintf(stderr,"pthread_create err %s\n",strerror(err));
        exit(1);
    }
    sleep(1);
    printf("End\n");
    exit(0);
}


线程的调度取决于调度器的测略

线程的终止

  1. 线程从启动例程返回,返回值就是线程的退出码
  2. 线程可以被同一进程的其他线程取消
  3. 线程调用pthread_exit()函数
  • pthread_exit();
static void *func(void *p){
    puts("thread is working");
    pthread_exit(NULL);
}

int main()
{
    printf("Begin\n");
    pthread_t ptid;

    int err = pthread_create(&ptid,NULL,func,NULL);
    if (err){
        fprintf(stderr,"pthread_create err %s\n",strerror(err));
        exit(1);
    }
    sleep(1);
    printf("End\n");
    exit(0);
}


  • pthread_join() 先当于进程的 wait()
static void *func(void *p){
    puts("thread is working");
    pthread_exit(NULL);
}

int main()
{
    printf("Begin\n");
    pthread_t ptid;

    int err = pthread_create(&ptid,NULL,func,NULL);
    if (err){
        fprintf(stderr,"pthread_create err %s\n",strerror(err));
        exit(1);
    }
    
    pthread_join(ptid,NULL);
    printf("End\n");
    exit(0);
}

线程/栈的清理

  • pthread_cleanup_push()
  • pthread_cleanup_pop()

类似钩子函数,程序只要正常终止,钩子函数就会被逆序调用,push 与 pop 可以指定操作

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

static void cleanup(void *p){
    puts(p);
}

static void *func(void *p){
    puts("Thread is working");

    pthread_cleanup_push(cleanup,"1");//这个函数是宏
    pthread_cleanup_push(cleanup,"2");
    pthread_cleanup_push(cleanup,"3");
    
    //pthread_exit(NULL);
    //下面的内容执行不到但是不会报错 会按照全为 1 处理

    pthread_cleanup_pop(1);//语法结构一定要对等
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(1);

    puts("push over");

    pthread_exit(NULL);
}

int main()
{
    pthread_t ptid;
    printf("Start !\n");

    int err = pthread_create(&ptid,NULL,func,NULL);//ptid 属性 处理函数 传参
    if (err){
        fprintf(stderr,"pthread_create() : %s\n",strerror(err));
        exit(1);
    }

    pthread_join(ptid,NULL);

    printf("End !\n");
    exit(0);
}

线程的取消选项

  • 多线程任务 有时需要取消部分任务(线程)
  • pthread_cancel()
  • 取消有2种状态
    • 不允许
    • 允许
      • 异步cancel
      • 推迟cancel(默认) 推迟到cancel点再响应
      • cancel点 : POSIX定义的cancel点 都是可能引发阻塞的系统调用
//示意

static void cleanup(void *){
    close(*p);
}

//cancel点
fd1 = open();
if (fd1 < 0){
    perror();
    exit(1);//只要调用exit 不管是 ezit(1) 还是 exit(0) 都是正常终止 都会执行线程清理函数
}
//在这收到一个取消请求 但因为下面的代码没有阻塞的系统调用 所以不会响应
pthread_cleanup_push(cleanup,&fd);
pthread)cleanup_pop(1);


//cancel点 下面的open是阻塞的系统调用 对上面的取消请求做出响应

fd2 = open();
if (fd2 < 0){
    perror();
    exit(1);
}
  • pthread_setcancelstate() 设置是否允许取消

  • pthread_testcancel() 什么都不做 本身就是一个取消点

  • 进程异常终止的条件之一

    • 最后一个线程对其取消请求作出响应
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#include <wait.h>
#include <string.h>

#define N 5
#define LEFT 30000000
#define RIGHT 30000200


static void *handler(void *p){
    int n = *(int *)p;
    int i,j,mark;
    for (i = LEFT+n;i <= RIGHT;i+=N){
        mark = 1;
        for (j = 2;j <= i/2;j++){
            if (i%j == 0){
                mark = 0;
                break;
            }
        }
        if (mark) {
            printf("%d is a primer [%d]\n",i,n);
        }
    }
    pthread_exit(p);

}

//交叉算法计算 池类算法涉及到竞争
int main()
{
    pthread_t Ptid[N];
    void *ptr = NULL;

    for (int n = 0;n < N;n++){
        int *num = malloc(sizeof(int));
        *num = n;
        int err = pthread_create(Ptid+n,NULL,handler,num);
        if (err){
            fprintf(stderr,"%s\n",strerror(err));
            exit(1);
        }
    }

    int n;
    for (n =0 ;n < N;n++){
        pthread_join(Ptid[n],ptr);
        free(ptr);
    }

    exit(0);
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值