LINUX系统编程之线程

[复制链接]

975

主题

975

帖子

629

积分

高级会员

Rank: 4

积分
629
分享到:
发表于 2022-7-11 14:55:46 | 显示全部楼层 |阅读模式
LINUX系统编程之线程
情景:
在双核虚拟机中有两个线程函数执行以下功能:
线程一:printf("hello\n");

线程二:printf("world\n");

程序运行时在单核状态下和双核状态下两个线程的执行顺序不一样,请问它们是根据怎样的规则进行调度的?

进程拥有自己的数据段,代码段,堆栈,占用资源多,开销大,通信不方便
为了减少系统开销,从进程中演化出了线程
线程存在于进程中,使用进程的资源

一、概述
线程是CPU调度和分配的基本单位,存在于进程中,是进程中的独立控制流
进程是系统中程序执行和资源分配的基本单位
线程自己不拥有资源
进程默认有一个控制线程(主线程)
线程依赖于进程存在,进程结束线程也结束
线程占用空间少
目的:
多任务程序设计
并发程序设计
网络程序
数据共享
多CPU并行

二、操作
void *fun(void *arg)

注意线程函数参数和返回值类型
pthread_t pth;

创建线程pthread_create(&pth, NULL, fun, (void *)arg);(可用结构体或数组传递多个参数)
等待线程结束回收其资源pthread_join(pth, NULL);

分离线程pthread_detach(pth);

退出线程pthread_exit();

取消线程pthread_cancle();

取消状态pthread_setcancelstate();

取消类型pthread_setcanceltype();

设置取消点pthread_testcancel();

清理pthread_cleanup_push();pthread_cleanup_pop();两个函数必须成对存在
编译gcc a.c 加-lpthread

gtk编程中多个线程可能使用同一资源照成界面冻结,所以要线程互斥
可使用gtk_threads_enter();和gtk_threads_leave();实现

三、线程的同步和互斥
互斥:多个任务访问同一公共资源,同一时刻只有一个任务可以访问
互斥锁和信号量
1.互斥锁:mutex,上锁解锁两种状态,解锁必须由上锁者完成
申请mutex,如果lock则阻塞申请者
pthread_mutex_t mutex;

pthread_mutex_lock(&mutex);

pthread_mutex_trylock(&mutex);

pthread_mutex_unlock(&mutex);

pthread_mutex_destroy(&mutex);

2.信号量
非负的整数计数器
对信号量进行减操作,如果为0则阻塞
PV原语,P减,V加
sem_t sem;

sem_init(&sem, 0, 1);

sem_wait(&sem);sem_trywait(&sem);

sem_post(&sem);

int val;

sem_getvalue(&sem, &val);

sem_destroy(&sem);

通过信号量同步操作实现多任务之间按照顺序运行
线程:无名信号量,进程:有名信号量
一个任务一个信号量
有名信号量
sem_t *sem_open("sem", O_RDWR);

sem_close(sem);

sem_unlink("sem");

有名信号量的名字在程序中和文件系统中不一样
有名信号量会保存之前的值所以使用前应该先删除再创建

实例:
有一个仓库生产者负责生产产品,并放入仓库,消费者从仓库拿走产品
要求仓
库每次只能入一人
仓库中最多存放10个产品,仓库满时不能再放入产品
仓库空时不能再从中取出产品
生产消费速度不同
思路:
生产和消费各一个线程,仓库为互斥,假设容量为10,库存为3

假设生产速度比消费速度快
信号量的值等于剩余产品
#include<stdio.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<semaphore.h>

int total=10;//总量
int last=7;//剩余量
sem_t sem_p;

sem_t sem_c;

void *produce(void *arg)

{

//sem_t *temp_semp=(sem_t *)arg;

while(1)

{

// sem_p=total-last;

if(9 >= last)

{

sleep(2);

sem_wait(&sem_p);

last++;

printf("in!last=%d\n",last);

sem_post(&sem_c);

}

}

}

void *cost(void *arg)

{

//sem_t *temp_semp=(sem_t *)arg;

while(1)

{

// sem_c=last;

if(1 <= last)

{

sem_wait(&sem_c);

last--;

printf("out!last=%d\n",last);

sem_post(&sem_p);

sleep(3);

}

}

}

int main()

{

pthread_t pth_p,pth_c;

sem_init(&sem_p,0,total-last);

sem_init(&sem_c,0,last);

printf("init_last=%d\n",last);

pthread_create(&pth_p,NULL,produce,NULL);

pthread_create(&pth_c,NULL,cost,NULL);

while(1);

return 0;

}

使用高级回帖 (可批量传图、插入视频等)快速回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则   Ctrl + Enter 快速发布  

发帖时请遵守我国法律,网站会将有关你发帖内容、时间以及发帖IP地址等记录保留,只要接到合法请求,即会将信息提供给有关政府机构。
快速回复 返回顶部 返回列表