LINUX系统编程之线程

发布时间:2020-05-28 21:52:08 作者:Czyy1
来源:网络 阅读:519

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;

}


推荐阅读:
  1. Windows多线程开发之并发线程程序研究
  2. Python之线程

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

linux系统编程 inux nux

上一篇:MapReduce程序之combiner规约

下一篇:微信jssdk 使用方法总结

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》