首页 > 系统相关 >3_linux多线程

3_linux多线程

时间:2022-10-22 10:59:15浏览次数:54  
标签:int void linux mutex pthread 线程 多线程 cond

3_linux多线程编程

基本概念

程序执行的最小单位

进程是线程的容器,不是基本执行单位,是线程容器

线程是进程中的不同执行路径, 有独立的堆栈、局部变量(因为线程需要线程函数

进程有自己的内存空间,线程在进程内,所以多进程程序比多线程健壮,但是进程切换开销大于线程切换。

基本api

需要-lpthred 编译选项,因为需要pthread库

线程开发基本概念有3个: 线程、互斥锁、条件

  • 线程操作: 创建,退出和等待3种状态。
//创建线程
	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;
}

  • 互斥锁操作:创建,销毁,加锁,解锁 4种操作
#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;
        }

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

  • 条件操作: 创建,销毁,触发,广播,等待 5种操作
#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;

标签:int,void,linux,mutex,pthread,线程,多线程,cond
From: https://www.cnblogs.com/hystill/p/16815546.html

相关文章

  • [Rocky Linux] 使用btrfs
    使用btrfsrocky本身并没有btrfs的相关管理工具,所以需要自己安装,但是遗憾的发现它的源中啥也没有。只能考虑自己安装。相关说明btrfsWiki(kernel.org)可以从中得到项......
  • Java多线程(1):线程生命周期
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 从事Java开发这些年来,如果要问我Java当中最难的部分是什么?最有意思的部分是什么?最多人讨论的部分是什么?那我会毫不犹豫......
  • smb linux 挂载参考说明
    主要记录下linux挂载smb的配置以及包含密码的使用说明软件包准备yuminstallcifs-utils挂载包含认证的,使用credentials配置选项//ser......
  • mysql for linux :安装及删除
    官网:https://downloads.mysql.com/archives/community/在官网找到适合自己版本的mysql,个人选择的是5.7.27、Redhat操作系统、操作系统版本7,X86平台64位。可以直接下载,也......
  • Centos7最小安装配置|Linux
    0.前言Linux/Centos7最小化安装后需要做的几件事1.快速安装$yuminstall-ynet-tools$yuminstall-ycurl$yuminstall-ywget$yum-yinstallvim$yum......
  • Linux find 命令
    Linux命令是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与......
  • Linux常用命令
    为提高大家使用Linux的效率,我个人总结了一些Linux常用命令,赶紧收藏起来吧!一.登录与注销系列1)sudouseraddlilei//添加用户(不能被立即使用,需设置密码sudopas......
  • Linux1
    Linux内核特征:1:内核组织形式为整体式结构2:进程调度方式简单有效3:支持内核进程(或称为守护进程)4:支持多平台虚拟内存管理5:虚拟文件系统6:模块机制7:增加了系统调用8:面向......
  • Linux struct sk_buff *skb 结构体
    structsk_buff是linux网络系统中的核心结构体,linux网络中的所有数据包的封装以及解封装都是在这个结构体的基础上进行。sk_buff是Linux网络中最核心的结构体,它用来管理......
  • 多线程基础知识
    【单核处理器和多核处理器的多线程】单核处理器:为每个线程分配时间片。来模拟并发多核处理器:一核一线程,真正实现并发 【标志】线程一致性,IsAlive就为true,否则为fals......