Linux系统编程—线程

在将线程之前就不得不再讲一下进程

进程与线程之间的关系

进程是资源分配的最小单位,线程是程序执行的最小单位,进程可以看做是一个控制线程,一个进程在同一时间只能做同一件事,而有多个控制线程,就能在同一时间做不同的事。一个线程属于一个进程,而一个进程可以有多个线程。进程是程序化的实例,是担当分配系统资源的基本单位,是分配系统资源的基本单位,一条线程指的是进程中一个单一顺序的控制流。线程包含了进程内执行环境必须的信息。

使用线程的原因

1,和进程相比线程所需要的资源更少,每开辟一个进程就需要分配给他独立的地址空间,建立众多的数据表来维护它的代码段,堆栈段和数据段
2,对于进程来说他们有独立的数据空间,要进行数据传递必须通过通信的方式,而线程由于在同一进程下共享数据空间,所以一个线程可以为其他线程直接所用
3,多线程是一种多任务,并发的工作方式

Linux上线程开发API

Linux常用线程库 pthread,多线程开发的基本思想:线程,互斥锁,条件

线程

线程创建 ,退出,等待

函数原型:

#include <pthread.h>
int pthread_creat(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
//成功返回0,失败返回-1
void pthread_exit(void* retval);
//用pthread_exit()来调用线程的返回值,用来退出线程,但是退出线程所占用的资源不会随着线程的终止而得到释放 
int pthread_join(pthread_t thread, void **retval);
//参数 :thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
//成功返回0,失败返回-1

示例代码

{
#include <stdio.h>
#include <pthread.h>
void *func1(void *arg)
{
    static char *p = "t1 is run out";
    printf("%ld thread is creat\n",(unsigned long)pthread_self());
    printf("param is %d\n",*((int *)arg));
    pthread_exit((void *)p);
}

int main({
    int ret;
    pthread_t t1;
    int param = 100;
    char *pret = NULL;
    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());
    pthread_join(t1,(void **)&pret);
    printf("main: t1 quit:%s\n",pret);
    return 0;
}

互斥量

定义:
互斥量从本质上来说像一把锁,在访问共享资源前对互斥量进行加锁,在访问完之后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量加锁的线程将会被阻塞到当前线程,直到当前线程释放该互斥锁,在设计时需要规定所以所有线程必须遵守相同的数据访问规则。

互斥量作用:
大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况变量归属单个线程,其他线程无法获得变量。但有的时候,线程间需要共享很多变量,通过数据的共享,完成线程间的交互。如果多个线程并发地共享变量,会出现数据不一致的问题,而互斥量可以使共享资源被唯一访问,能很好地解决这个问题。

1,创建及销毁互斥锁

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t mutex);
//返回:若成功返回0,否则返回错误编号

示例代码:

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

void *func1(void *arg)

{
    static char *p = "t1 is run out";
    printf("%ld thread is creat\n",(unsigned long)pthread_self());
    printf("param is %d\n",*((int *)arg));
    pthread_exit((void *)p);
}


int main()
{
    int ret;
    pthread_t t1;
    int param = 100;
    char *pret = NULL;
    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());
    pthread_join(t1,(void **)&pret);
    printf("main: t1 quit:%s\n",pret);
    return 0;
}

2,加锁及解锁

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex mutex);
int pthread_mutex_trylock(pthread_mutex_t mutex);
int pthread_mutex_unlock(pthread_mutex_t mutex);
//返回:若成功返回0,失败返回错误编码

示例代码:

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

int g_data = 0;

pthread_mutex_t mutex;

void *func1(void *arg)
{

    int i;
    pthread_mutex_lock(&mutex);
    for(i=0;i<5;i++){
       printf("t1:%ld thread is creat\n",(unsigned long)pthread_self());
       printf("t1:param is %d\n",*((int *)arg));
       sleep(1);
    }
    pthread_mutex_unlock(&mutex);
}

void *func2(void *arg)
{
    printf("t2:%ld thread is creat\n",(unsigned long)pthread_self());
    printf("t2:parm is %d\n",*((int *)arg));
}


int main()
{
    int ret;
    pthread_t t1;
    pthread_t t2;


    pthread_mutex_init(&mutex, NULL);

    int param = 100;
    char *pret = NULL;

    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }

    ret = pthread_create(&t2, NULL, func2,(void *)&param);
    if(ret == 0){
    printf("creat t2 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);

    pthread_mutex_destroy(&mutex);

    return 0;
}

3,互斥锁对共享内存的影响

示例代码

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

int g_data = 0;

pthread_mutex_t mutex;

void *func1(void *arg)
{
    printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
    printf("ti:parm is %d\n",*((int *)arg));
    pthread_mutex_lock(&mutex);
    while(1){
       printf("t1: %d\n",g_data++);
       sleep(1);
    }
    if(g_data == 3){
       pthread_mutex_unlock(&mutex);//只有满足条件才能解锁
       pthread_exit(NULL);
    }
}

void *func2(void *arg)
{
    printf("t2:%ld thread is creat\n",(unsigned long)pthread_self());
    printf("t2:parm is %d\n",*((int *)arg));
    while(1){
            printf("t2: %d\n",g_data);
            pthread_mutex_lock(&mutex);
            g_data++;
            pthread_mutex_unlock(&mutex);
            sleep(1);
    }
}


int main()
{
    int ret;
    pthread_t t1;
    pthread_t t2;

    pthread_mutex_init(&mutex, NULL);
int param = 100;
    char *pret = NULL;

    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }

    ret = pthread_create(&t2, NULL, func2,(void *)&param);
    if(ret == 0){
    printf("creat t2 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());
    while(1){
          printf("main: %d\n",g_data++);
          sleep(1);
    }
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
    pthread_mutex_destroy(&mutex);
    return 0;
}
            

在这里插入图片描述

测试结果:
可以使用下面的解决方案:互斥量保存在共享内存中,在初始化该锁的时候,设置为进程间共享,这样两个进程连接到共享内存后,都可以获得这个互斥锁,因为已经设置了进程间共享,所以对锁的访问的冲突问题,系统已经解决了。

4,死锁的情况

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

int g_data = 0;

pthread_mutex_t mutex;
pthread_mutex_t mutex2;

void *func1(void *arg)
{

    int i;
    pthread_mutex_lock(&mutex);
    pthread_mutex_lock(&mutex2);
    for(i=0;i<5;i++){
       printf("t1:%ld thread is creat\n",(unsigned long)pthread_self());
       printf("t1:param is %d\n",*((int *)arg));

       sleep(1);
    }
    pthread_mutex_unlock(&mutex);
}

void *func2(void *arg)
{

    pthread_mutex_lock(&mutex2);
    pthread_mutex_lock(&mutex);
    printf("t2:%ld thread is creat\n",(unsigned long)pthread_self());
    printf("t2:parm is %d\n",*((int *)arg));
    pthread_mutex_unlock(&mutex2);
}


int main()
{
    int ret;
    pthread_t t1;
    pthread_t t2;

   pthread_mutex_init(&mutex, NULL);

    int param = 100;
    char *pret = NULL;

    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }

    ret = pthread_create(&t2, NULL, func2,(void *)&param);
    if(ret == 0){
    printf("creat t2 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);

    pthread_mutex_destroy(&mutex);
    pthread_mutex_destroy(&mutex2);
    return 0;
}

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

线程条件控制实现线程同步

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

int g_data = 0;

pthread_mutex_t mutex;
pthread_cond_t cond; 
 
void *func1(void *arg)
{
    printf("t1:%ld thread is create\n",(unsigned long)pthread_self());
    printf("ti:parm is %d\n",*((int *)arg));
    static int cnt = 0;
    while(1){   
            pthread_cond_wait(&cond,&mutex); 
            printf("t1  run\n");
            printf("t1: %d\n",g_data);
            g_data = 0;
            sleep(1);
            if(cnt++ == 10){
            exit(1);
            }
    }
}

void *func2(void *arg)
{
    printf("t2:%ld thread is creat\n",(unsigned long)pthread_self());
    printf("t2:parm is %d\n",*((int *)arg));
  
    while(1){
            printf("t2: %d\n",g_data);
            pthread_mutex_lock(&mutex);
            g_data++;
            pthread_mutex_unlock(&mutex);
            if(g_data == 3){
              pthread_cond_signal(&cond);
            }
            sleep(1);
    }
}


int main()
{
    int ret;
    pthread_t t1;
    pthread_t t2;    
    
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond,NULL);
    int param = 100;

    ret = pthread_create(&t1, NULL,func1, (void *)&param);
    if(ret == 0){
    printf("creat t1 success\n");
    }

    ret = pthread_create(&t2, NULL, func2,(void *)&param);
    if(ret == 0){
    printf("creat t2 success\n");
    }
    printf("main:%ld\n",(unsigned long)pthread_self());
    while(1){
          printf("main: %d\n",g_data++);
          sleep(1);
    }
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
    
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

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

本文存在不足会后续补充,仅作为学习记录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值