当前位置:   article > 正文

Linux:线程_linux有线程嘛

linux有线程嘛
线程的实现方式

在操作系统中,线程的实现有以下三种方式:

  1. 内核级线程
  2. 用户级线程
  3. 组合级线程
    在这里插入图片描述
    Linux 中线程的实现

Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。 Linux 把所有的线程都当做进程来实现。内核并没有准备特

别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯一隶属

于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。
线程库中的接口介绍

#include <pthread.h>
/*
pthread_create()用于创建线程
thread: 接收创建的线程的 ID
attr: 指定线程的属性
start_routine: 指定线程函数
arg: 给线程函数传递的参数
成功返回 0, 失败返回错误码
*/
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
/*
pthread_exit()退出线程
retval:指定退出信息    向外界传递的参数
*/
int pthread_exit(void *retval);
/*
pthread_join()等待 thread 指定的线程退出,线程未退出时,该方法阻塞
retval:接收 thread 线程退出时,指定的退出信息  
*/
int pthread_join(pthread_t thread, void **retval);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
线程同步

​ 线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资源进行操作,直到该线程完成操作, 其他线程才

能操作,也就是协同步调,让线程按预定的先后次序进行运行。 线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。

编写下列程序,将index在五个进程上一起加1000次

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

int _index=1;
void *thread_fun(void * arg)
{
    for(int i=0; i<1000; i++)
    {
        printf("_index=%d\n",_index++);
    }
}

int main()
{
    pthread_t id[5];
    int i=0;
    for(;i<5; i++ )
    {
        pthread_create(&id[i],NULL,thread_fun,NULL);
    }

    for(i=0; i<5; i++)
    {
        pthread_join(id[i],NULL);
    }
    exit(0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

第一次运行:
在这里插入图片描述

第二次运行:
在这里插入图片描述

第三次运行:
在这里插入图片描述
说明线程在对index的加操作上不是完全独立的,如果两个线程同时对index进行加操作,那index的值增加就会少一次,所以每次运行的值都不一样。

对程序添加上信号量,每个线程进行index加操作都要PV操作,这样index值就会固定,线程就同步了

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

sem_t sem;
int _index=1;
void *thread_fun(void * arg)
{
    for(int i=0; i<1000; i++)
    {
        sem_wait(&sem);//P
        printf("_index=%d\n",_index++);
        sem_post(&sem);//V
    }
}

int main()
{
    sem_init(&sem,0,1);
    pthread_t id[5];
    int i=0;
    for(;i<5; i++ )
    {
        pthread_create(&id[i],NULL,thread_fun,NULL);
    }

    for(i=0; i<5; i++)
    {
        pthread_join(id[i],NULL);
    }
    exit(0);
    sem_destroy(&sem);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

运行结果:
在这里插入图片描述
互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • 1
  • 2
  • 3
  • 4
  • 5

信号量

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_destroy(sem_t *sem);
  • 1
  • 2
  • 3
  • 4
  • 5

条件变量

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond); //唤醒单个线程
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒所有等待的线程
int pthread_cond_destroy(pthread_cond_t *cond);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

读写锁

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwlock, pthread_rwlockattr_t *attr);
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
线程安全

多线程程序无论调度顺序怎样,都能得到一个正确的结果,就处于一个线程安全状态

要保证线程安全需要做到:

1) 对线程同步,保证同一时刻只有一个线程访问临界资源。

2) 在多线程中使用线程安全的函数(可重入函数),所谓线程安全的函数指的是:如果一个

函数能被多个线程同时调用且不发生竟态条件,则我们程它是线程安全的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/336579
推荐阅读
相关标签
  

闽ICP备14008679号