POSIX线程 | 信号量、互斥锁、条件变量

本文介绍了POSIX线程的概念,包括线程的优缺点、线程函数如pthread_create()、pthread_exit()和pthread_join()。通过代码示例展示了如何使用信号量、互斥锁和条件变量实现线程同步,并提供了一个线程安全的字符串分割函数的示例。
摘要由CSDN通过智能技术生成

什么是线程

线程其实就是进程内部的一条执行路径或控制序列。

一个进程在同一时刻只做一件事情。有了多个控制线程以后,在程序设计时可以把进程设计成在同一时刻能够做不止一件事,每个线程处理各自独立的任务。

线程的优缺点

优点

  • 通过为每种事件类型的处理分配单独的线程,能够简化处理异步时间的代码。
  • 多个线程可以自动共享相同的存储地址空间和文件描述符。
  • 对于数据库服务器来说,这个明显的多任务工作如果用多进程方式将很难做到高效的完成,因为各个不同的进程必须紧密合作才能加锁和数据一致性方面的要求,而如果用多线程完成的话明显要比多进程容易得多。
  • 一般而言,线程之间的切换需要操作系统所做的工作远远要比进程切换做的工作少,因此多个线程对资源的需求远远小于多个进程的需求。

缺点

  • 对多线程程序的调试远远要比单线程程序调试困难得多,因为线程之间的交互非常难于控制。
  • 编写多线程程序往往需要非常仔细的设计,在多线程程序中,因为时序上的细微偏差或无意造成的变量共享而引发错误的可能性是很大的。
线程函数
pthread_create()

定义如下:

 #include <pthread.h>
 int pthread_create(pthread_t * thread, pthread_attr_t * attr, 
 void * (*start_routine)(void *), void * arg);
  • thread是新线程的标识符,pthread*函数通过它来引用新线程。pthread_t是一个整形类型.
  • attr参数用于设置新线程的属性,给他传递NULL表示使用默认的线程属性。
  • start_routine和arg参数分别指定新线程将运行的函数及其参数。
  • pthread_create()成功时返回0;失败时返回错误码。
pthread_exit()

线程一旦被创建好,内核就可以调度内核线程来执行start_routine函数指针所指向的函数了,函数结束的时候调用pthread_exit(),以确保安全的退出。

 #include <pthread.h>
 void pthread_exit(void *retval);
  • pthread_exit()函数通过retval参数向线程回收者传递其退出信息。
  • 它执行完不会返回到调用者,而且永远不会失败。
pthread_join()

一个进程中的所有线程都可以调用pthread_join()函数来回收其他的线程,即就是等待其他的线程结束,这类似于回收进程的wait()系统调用。pthread_join()定义如下:

    #include <pthread.h>
    int pthread_join(pthread_t thread, void **thread_return);  
  • thread参数是目标线程的标识符,thread_return是目标线程返回的退出信息。
  • 这个函数会一直被阻塞着,一直到被回收的线程结束为止。
  • 成功时返回0,失败时返回错误码。

可能的错误码如下:

错误码 描述
EDEADLK 可能引起死锁,比如两个线程互相针对对方调用pthread_join(),或者对自身调用pthread_join()
EINVAL 目标线程是不可回收的,或者已经有线程在回收该目标线程
ESRCH 目标线程不存在
代码示例

a.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<pthread.h>
void* thread_fun(void* arg)
{
   
    int i=0;
    for(;i<10;i++)
    {
   
        printf("fun run\n");
        sleep(1);
    }
    pthread_exit("fun over\n");
}

int main()
{
   
    pthread_t id;
    pthread_create(&id,NULL,thread_fun,NULL);	//开启线程
    
    int i=0;
    for(;i<5;i++)
    {
   
        printf("main run\n");
        sleep(1);
    }
    //pthread_exit(NULL);      

    char*s=NULL;
    pthread_join(id,(void**)&s);	//等待子线程
    printf("s=%s\n",s);

    printf("main over\n");

}

在这里插入图片描述

b.c

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

#define MAXID 5
void* thread_fun(void* arg)
{
   
    int index=(int)arg;
    int i=0;
    for(;i<4;i++
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值