Linux最全的多线程编程

1、进程与线程
进程是资源分配的最小单位,线程是程序执行的最小单位,在面向线程设计的系统中,进程本身不是基本运行单位,而是线程的容器。父进程通过fork一个子进程,是将相关代码进行拷贝,会消耗内存空间,线程是一个进程中不同的执行路径,有自己的堆栈,局部变量,没有独立的地址空间。一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但进程切换时,消耗资源大,效率低。对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
2、线程开发API概要
多线程开发在 Linux 平台上已经有成熟的 pthread 库支持,在编译的过程中要加 -lpthread。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,销毁,加锁和解锁。条件操作有 5 种操作:创建,销毁,触发,广播和等待。

函数原型

#include <pthread.h>
//线程创建
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数一:线程id
参数二:线程属性,默认可置为NULL,表示线程属性取缺省值
参数三:线程入口函数
参数四:*线程入口函数的参数
//线程退出
 void pthread_exit(void *retval);
 参数:线程退出时的返回值,也可为NULL
//线程等待
 int pthread_join(pthread_t thread, void **retval);
 参数二:收回线程的退出状态线程的返回值不感兴趣,可以把rval_ptr置为NULL
 //获取线程ID
 pthread_t pthread_self(void);

demo实例

#include <stdio.h>
#include <pthread.h>
void *func(void *arg)
{
        static char *p = "xiaobian henshuai";
        printf("this is t1 thread pid=%ld\n",(unsigned long)pthread_self());
        printf("deliver param is %d\n",*(int *)arg);
        pthread_exit((void *)p);
        //退出时返回退出时的状态,返回一个字符串
}
int main()
{
        pthread_t t1;
        char *p =NULL;
        int param = 10;
        pthread_create(&t1,NULL,func,(void*)&param);
        //创建线程时,传递了一个param参数
        pthread_join(t1,(void **)&p);
        //等待t1线程的退出,用p收集,t1线程退出时的状态
        printf("return value is %s\n",p);
        return 0;
}
执行结果
this is t1 thread pid=140537713628928
deliver param is 10
return value is xiaobian henshuai

函数原型

#include <pthread.h>
//互斥锁的初始化
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
参数一:互斥锁变量mutex
参数二:通常为NULL,为默认参数
//销毁互斥锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
//解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

demo实例

#include <stdio.h>
#include <pthread.h>
int data = 0;//定义一个全局变量验证线程是共享内存空间的
pthread_mutex_t mutex;
void *func1(void *arg)
{
         static char *p = "xiaobian henshuai";
         printf("t1:this is t1 thread pid=%ld\n",(unsigned long)pthread_self());
         printf("t1:deliver param is %d\n",*(int *)arg);
         int i=3;
         pthread_mutex_lock(&mutex);//加锁的目的是在执行以下代码的过程中不会被其他的进程打断
         while(i--)
         {
                 printf("t1:data=%d\n",data++);
                 sleep(1);
         }
         pthread_mutex_unlock(&mutex);
         pthread_exit((void *)p);
}

void *func2(void *arg)
{
        pthread_mutex_lock(&mutex);
        static char *p = "xiaobian henshuai";
        printf("t2:this is t2 thread pid=%ld\n",(unsigned long)pthread_self());
        printf("t2:deliver param is %d\n",*(int *)arg);
        while(1)
        {
                printf("t2:data=%d\n",data++);
                sleep(1);
        }
        pthread_mutex_unlock(&mutex);
        pthread_exit((void *)p);
}
int main()
{
        pthread_t t1;
        pthread_t t2;
        char *p =NULL;
        int param = 10;
        pthread_create(&t1,NULL,func1,(void*)&param);
        pthread_create(&t2,NULL,func2,(void*)&param);
        pthread_mutex_init(&mutex,NULL);
        pthread_join(t1,(void **)&p);
        pthread_join(t2,(void **)&p);
        pthread_mutex_destroy(&mutex);
        printf("main:return value is %s\n",p);
        return 0;
        }
执行结果
t1:this is t1 thread pid=139923829593856
t1:deliver param is 10
t1:data=0
t1:data=1
t1:data=2
t2:this is t2 thread pid=139923821201152
t2:deliver param is 10
t2:data=3
t2:data=4
t2:data=5
t2:data=6
t2:data=7
t2:data=8
^C

死锁是怎么产生的:
前提是有两个锁,线程一获得锁一的同时,又想获得锁二,线程二获得锁二的同时,又想获得锁一,线程一和二都想拿到对方的锁,导致线程停滞不前。

函数原型

#include <pthread.h>
//创建条件变量
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
//销毁条件变量
int pthread_cond_destroy(pthread_cond_t* cond);
//等待
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
//触发
int pthread_cond_signal(pthread_cond_t c*ond)
//广播
int pthread_cond_broadcast(pthread_cond_t cond);

demo实例

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int data = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *func1(void *arg)
{
        printf("t1:this is t1 thread pid=%ld\n",(unsigned long)pthread_self());
        printf("t1:deliver param is %d\n",*(int *)arg);
        while(1)
        {
                pthread_cond_wait(&cond,&mutex);//等待某个条件的唤醒
                printf("t1 run========\n");
                data=0;
        }
}
void *func2(void *arg)
{
        printf("t2:this is t2 thread pid=%ld\n",(unsigned long)pthread_self());
        printf("t2:deliver param is %d\n",*(int *)arg);
        while(1)
        {
                printf("t2:data=%d\n",data);
                pthread_mutex_lock(&mutex);
                data++;
                if(data==3)
 		{
                        pthread_cond_signal(&cond);//唤醒条件执行线程t1
                }
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}
int main()
{
        pthread_t t1;
        pthread_t t2;
        char *p =NULL;
        int param = 10;
        pthread_create(&t1,NULL,func1,(void*)&param);
        pthread_create(&t2,NULL,func2,(void*)&param);
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);
        pthread_join(t1,(void **)&p);
        pthread_join(t2,(void **)&p);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        printf("main:return value is %s\n",p);
        return 0;
执行结果
t2:this is t2 thread pid=140397643106048
t2:deliver param is 10
t2:data=0
t1:this is t1 thread pid=140397651498752
t1:deliver param is 10
t2:data=1
t2:data=2
t1 run========
t2:data=0
t2:data=1
t2:data=2
t1 run========
t2:data=0
t2:data=1
t2:data=2
t1 run========
t2:data=0
^C
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值