IO 笔记

发布于:2024-12-18 ⋅ 阅读:(35) ⋅ 点赞:(0)
……接上文

线程的函数接口

创建线程(pthread_create)

头文件
#include <pthread.h>
int pthread_create(pthread_t  *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
功能:创建一个线程
参数:1.pthread_t *thread:线程标识,成功创建线程后,pthread_create 会将新线程的 ID 写入 thread 指向的内存位置。
      2.const pthread_attr_t *attr:线程属性, NULL:代表设置默认属性
      3. void *(*start_routine):函数名,代表线程函数,指向一个函数的指针,这个函数就是线程的执行体(也就是线程的入口函数)。该函数必须符合 void *(*start_routine)(void *) 的原型,即接受一个 void * 类型的参数,并返回一个 void * 类型的值。
 4.void *arg:传递给 start_routine 的参数。arg 是一个通用的指针,可以传递任何类型的数据(通常是一个结构体的指针,以便传递多个参数)。如果不需要传递参数,可以传递 NULL
 
返回值:成功返回0
        失败返回错误码


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

void *mythread(void *arg)
{
    printf("子线程执行结束\n");
}
int main(int argc, char const *argv[])
{
    pthread_t tid;
    //创建一个线程
    if(pthread_create(&tid,NULL,mythread,NULL))
    {
        printf("create failed\n");
        return -1;
    }
    printf("主线程执行中。。。\n");
    sleep(2);
    printf("主线程执行结束\n");
    return 0;
}

线程退出函数(pthread_exit)

void pthread_exit(void *retval);功能:用于执行退出线程
参数:任意类型的数据,一般写NULL
返回值:无
pthread_exit(NULL);

通过 retval 参数,当前线程可以向其他线程返回执行状态或结果。这个状态信息可以通过 pthread_join 函数获取。

线程回收函数(pthread_join/pthread_detach)

int pthread_join(pthread_t thread, void **retval);
功能:用于等待一个指定的线程结束,阻塞函数
参数:thread:创建的线程对象 
      void **retval: 指针*retval指向线程返回的参数,一般是NULL
返回值:成功 : 0
       失败:errno


int pthread_detach(pthread_t thread);
功能:让线程结束时自动回收线程资源,让线程和主线程分离
参数:thread:线程ID
返回值:成功 : 0
       失败:errno

#include <stdio.h>
#include <pthread.h>
//线程函数
void *thread(void *arg)
{
    int *num = (int *)arg;
    printf("子线程执行中\n");
    sleep(4);
    pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
    //创建一个线程
    pthread_t tid;  //线程标识
    int value = 10;
    if(pthread_create(&tid,NULL,thread,(void*)&value))
    {
        printf("creat err");
        return -1;
    }
    //不阻塞等待,分离子线程,自己回收
    pthread_detach(tid);
    阻塞回收线程
    pthread_join(tid,NULL);
    printf("线程接着执行\n");
    return 0;
}

获取线程号(pthread_self)

pthread_t pthread_self(void);
功能:
    获取线程号
返回值:
    成功:调用此函数线程的ID

线程同步

线程之间是很容易进行通信的,能够通过全局变量实现数据的共享和交换,也就是通过访问临界资源,但是多个线程在同时访问共享数据的对象时需要引入同步和互斥机制。

临界资源:一次仅允许一个线程访问的资源

概念

同步(synchronization)指的是多个任务(线程)按照约定的顺序相互配合完成一件事情

线程的通信机制

信号量

在linux当中信号量的分类

  1. 内核信号量

由内核控制路径使用

  1. Posix信号量

a.无名信号量:数据存储在内存中,通常在线程间使用或父子进程间

函数接口:sem_init\sem_wait\sem_post

b.有名信号量:数据存储在文件中,在进程间线程间都可以使用

函数接口:sem_open\sem_wait\sem_post\sem_close

  1. System V信号量

是信号量的集合,叫信号灯集,属于IPC对象

函数接口:semget\semctl\semop

无名信号量

信号量:通过信号量实现同步操作,由信号量决定线程是继续运行还是阻塞等待。

信号量代表的是某一类资源,它的值表示系统中该资源的数量,信号量>0的话,表示有资源可以使用,可以申请到资源,继续执行程序,信号量<= 0的话,表示没有资源可以使用,无法申请到资源,阻塞。

信号量是一个受保护的量,只能通过三种操作来访问:

  1. 初始化信号量:sem_init()
  2. P操作,申请资源:sem_wait() 资源-1
  3. V操作,释放资源:sem_post() 资源+1

注意:信号量是一个非负的整数,所以一定是(>=0)

相关的函数接口

int  sem_init(sem_t *sem,  int pshared,  unsigned int value)  
功能:初始化信号量   
参数:sem:初始化的信号量对象
    pshared:信号量共享的范围(0: 线程间使用   非0:1进程间使用)
    value:信号量初值
返回值:成功 0
      失败 -1

互斥概念

互斥:多个线程在访问临界资源时,同一时间只能一个线程进行访问

互斥锁

概念

互斥锁:通过互斥锁可以实现互斥机制,主要用来保护临界资源,每个临界资源都由一个互斥锁来保护,线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。

函数接口

int  pthread_mutex_init(pthread_mutex_t  *mutex, pthread_mutexattr_t *attr)  
功能:初始化互斥锁  
参数:mutex:互斥锁
    attr:  互斥锁属性  //  NULL表示缺省属性
返回值:成功 0
      失败 -1
      
int  pthread_mutex_lock(pthread_mutex_t *mutex)   
功能:申请互斥锁     
参数:mutex:互斥锁
返回值:成功 0
      失败 -1

int  pthread_mutex_unlock(pthread_mutex_t *mutex)   
功能:释放互斥锁     
参数:mutex:互斥锁
返回值:成功 0
      失败 -1
      
int  pthread_mutex_destroy(pthread_mutex_t  *mutex)  
功能:销毁互斥锁     
参数:mutex:互斥锁

                                                                                                                                 未完待续……


网站公告

今日签到

点亮在社区的每一天
去签到