线程(Linux)(C)

13 篇文章 0 订阅

特殊的进程

线程是任务执行的最小单位

多线程公用一片进程空间

  • 多线程共享的数据:

指令

静态数据

文件描述符

用户ID

用户组ID

工作目录

信号处理函数

  • 多线程不共享的数据:

堆栈(栈空间)

程序计数器

线程ID

线程属性(状态、优先级)

错误号

信号掩码

  • 线程相关函数调用(第三方库函数)

  • 线程创建

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

返回值:成功返回0,失败为非0

thread:存储线程ID的地址

attr:创建时的属性

start_routine:线程执行函数的入口地址

arg:传递给线程执行函数的参数

  • 线程回收

#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);

功能:阻塞等待线程,回收其资源

返回值:成功0,失败非0

thread:线程id

retval:线程结束时留下的信息

  • 线程退出

#include <pthread.h>

void pthread_exit(void *retval);

功能:主动退出线程(当前线程退出)

retval:留下的信息

  • 线程分离

#include <pthread.h>

int pthread_detach(pthread_t thread);

功能:分离线程,线程退出时不需要回收,由系统回收。

threa:线程id

  • 线程取消

#include <pthread.h>

int pthread_cancel(pthread_t thread);

功能:线程取消,取决于其状态与属性

thread:线程id

  • 线程间通信

同一线程下的不同线程都共享同一片内存空间。线程又是以函数为执行单位,使用全局变量通信最为方便

需要添加同步互斥机制

  • 互斥锁

保护某一段代码(临界资源),互斥锁本身是系统中的一种资源,

如要使用互斥锁保护的代码,需要向系统申请资源

  • 定义互斥锁

pthread_mutex_t mutex;//互斥锁变量类型

  • 初始化锁资源

int pthread_mutex_init (pthread_mutex_t* mutex, pthread_mutexattr_t * attr);

功能:锁资源的初始化,在系统中定义出来的一种锁,并且初始化这个锁的个数为1

返回值:成功为0

mutex:锁对象,存储锁的地址

mutexattr:锁的属性,默认属性传入NULL

  • 申请锁(加锁)

int pthread_mutex_lock(pthread_mutex_t* mutex);

功能:向系统申请参数列表中的锁资源,如果系统中有这个资源,那么代码可以继续往后执行,

并且这种资源的个数-1。若没有,代码会阻塞等待。

mutex:要申请的锁资源

  • 释放锁(解锁)

int pthread_mutex_unlock(pthread_mutex_t* mutex);

功能:向系统中释放一种资源,使数目+1

  • 摧毁锁

int pthread_mutex_destory(pthread_mutex_t* mutex);

功能:释放动态初始化的互斥锁变量,防止内存泄漏

  • 信号量

也是系统中的一种资源,可以有多个,实现同步进制。

  • 头文件

#include <semaphore.h>

  • 定义

sem_t sem;//变量类型

  • 信号量初始化

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:向系统中声明一种信号量资源,这种资源可以有多个,方便P/V操作

返回值:成功0,失败-1

sem:信号量对象,存储信号量的地址

pshared:0表示线程共用,非0表示进程之间共用

value:信号量初始化个数

  • 请求信号量

int sem_wait(sem_t *sem);

功能:申请系统中的信号量资源,若能够申请到,并且信号量-1。若没有信号量,则阻塞等待。

返回值:成功0,失败-1

sem:信号量对象

  • 释放信号量

int sem_post(sem_t *sem);

功能:向系统中释放一种信号量资源,使数目+1

返回值:成功0,失败-1

sem:信号量对象

  • 摧毁信号量

int sem_destroy(sem_t *sem);

功能:释放动态初始化的信号量变量,防止内存泄漏

  • 部分代码示例

//线程的创建
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *func01(void *a)
{
    int *o=(int *)a;
    int *p=(int *)a;
    while(1)
    {
        printf("pthread01:%d\n",*p);
        if(p==o+9)
        {
            p=a;
        }
        p++;
        sleep(1);
    }
}
void *func02(void *a)
{
    int *o=(int *)a;
    int *p=(int *)a+9;
    while(1)
    {
        printf("pthread02:%d\n",*p);
        if(p==o)
        {
            p=o+9;
        }
        p--;
        sleep(1);
    }
}
int main(int argc, char *argv[])
{ 
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int *q=arr;
    q=(void *)q;
    void *(*p)(void *)=func01;
    pthread_t pid;
    pthread_create(&pid,NULL,p,q);
    p=func02;
    pthread_create(&pid,NULL,p,q);
    while(1);
} 
//等待子线程结束
#include <stdio.h>
#include <pthread.h>
void *fun01(void *arg)
{
    printf("Im child\n");
    pthread_exit("bye bye");
}
int main(int argc, char *argv[])
{ 
    pthread_t id;
    pthread_create(&id,NULL,fun01,NULL);
    printf("Im parent\n");
    char *ret;
    pthread_join(id,(void**)&ret);
    printf("child say %s\n",ret);
    printf("parent say over\n");
    return 0;
} 
//互斥锁
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int a[2]={2,2};
pthread_mutex_t mutex;
void *func01(void *arg)
{
    //int *p=(int *)arg;
    while(1)
    {
        pthread_mutex_lock(&mutex);
        if(a[0]==a[1])
        {
            printf("child: %d equal %d\n",a[0],a[1]);
        }
        else
        {
            printf("child: %d unequal %d\n",a[0],a[1]);
        }
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}
int main(int argc, char *argv[])
{ 
    pthread_t id;
    pthread_create(&id,NULL,func01,(void *)a);
    pthread_mutex_init(&mutex,NULL);
    while(1)
    {
        pthread_mutex_lock(&mutex);
        a[0]++;
        a[1]++;
        pthread_mutex_unlock(&mutex);
        //sleep(1);
    }
    return 0;
} 
//信号量
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t semr,semw;
char buf[64];

void *func(void *arg)
{
    while(1)
    {
        sem_wait(&semr);
        printf("%s\n",buf);
        sem_post(&semw);
    }
}
int main(int argc, char *argv[])
{ 
    pthread_t id;
    pthread_create(&id,NULL,func,NULL);
    sem_init(&semr,0,0);
    sem_init(&semw,0,1);
    while(1)
    {
        sem_wait(&semw);
        fgets(buf,sizeof(buf),stdin);
        sem_post(&semr);
    }
    return 0;
} 
//信号量实现互斥锁
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
sem_t sem;
void *func(void *arg)
{
    while(1)
    {
        sem_wait(&sem);
        printf("Im child pthread\n");
        sem_post(&sem);
        sleep(1);
    }
}
int main(int argc, char *argv[])
{ 
    pthread_t pth;
    pthread_create(&pth,NULL,func,NULL);
    sem_init(&sem,0,1);
    while(1)
    {
        sem_wait(&sem);
        printf("Im main pthread\n");
        sem_post(&sem);
        sleep(1);
    }
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值