概述
声明:侵删
文章目录
- 1. 线程和进程的区别
- 2.prhread线程库相关API
- 3.线程间的同步和互斥
- 4.互斥锁
- 5.互斥锁例程
- 6.POISX信号量 [System V 信号量参考此文](https://blog.csdn.net/qq_43921241/article/details/103123667)
- 7.POSIX信号量例程
1. 线程和进程的区别
进程 :每个进程有自己独立的地址空间
Linux为每个进程创建task_struct (任务结构体,存放进程属性)
每个进程都参与内核调度,不影响其他进程
线程:进程在切换时系统开销大
很多操作系统引入了轻量级进程LWP(线程)
同一进程中的线程共享相同地址空间
Linux不区分进程、线程(Linux都认为成一个任务)
一个进程中的多个线程共享一下资源
线程ID
PC和相关寄存器
堆栈
errno
优先级
执行状态和属性
2.prhread线程库相关API
编译时候要注意链接pthread线程库
线程创建函数:pthread_creat
线程回收函数: pthread_join
线程退出函数:pthread_exit
3.线程间的同步和互斥
线程共享进程的空间地址和资源,对这些资源进行操作是必须注意线程间的同步和互斥。本文主要介绍POSIX的两种互斥机制: 信号量和互斥锁。
互斥锁适用于同时可用资源唯一的情况,信号量适合于同时可用资源为多个的情况。
4.互斥锁
互斥锁是一种以简单的加锁方式对共享资源的原子操作。互斥锁有两种状态:上锁和解锁。在同一时刻只有一个线程可以掌握互斥锁,拥有上锁状态的线程可以对共享资源进行操作,其余线程想要抢锁就会挂起直到拥有锁的进程释放锁。
互斥锁可以分为快速互斥锁、递归互斥锁、检错互斥锁。
快速锁:调用线程必须堵塞到拥有锁的进程释放锁为止
递归锁:递归锁能够成功的返回,并能增加调用线程在互斥上加锁的次数
检错锁:相当于非堵塞版的快速锁,抢不到锁不会堵塞会返回一个错误信息。
默认是快速互斥锁。
使用互斥锁之前必须初始化锁的类型。
互斥锁相关API
互斥锁初始化函数 pthread_mutex_init
互斥锁控制函数:上锁、解锁、检查锁、删除锁、
5.互斥锁例程
/*mutex.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define THREAD_NUM 3 /*线程数*/
#define TASKK_NUM 3 /*每个线程执行的小任务数*/
#define DELAY_TIME 10 /*每个小任务最大时间间隔*/
pthread_mutex_t mutex; /*定义互斥锁*/
/*线程函数*/
void * func_thread(void *arg)
{
int thread_num = (int) arg;
int delay_time = 0;
int count = 0;
if (pthread_mutex_lock(&mutex) == -1)/*抢锁*/
{
perror("pthread_mutex_lock");
pthread_exit(NULL);
}
printf("The thread [%d] is beginningn",thread_num);
for(count = 0; count<TASKK_NUM;count++)
{
delay_time =(int)(rand()%DELAY_TIME)+1; /*产生随机数1-DLY_TIME*/
sleep(delay_time);
printf("tthread[%d],job[%d],sleep[%d]sn",thread_num,count,delay_time);
}
printf("pthread[%d] endn",thread_num);
pthread_mutex_unlock(&mutex);/*解锁*/
pthread_exit(NULL);
}
int main()
{
pthread_t tid[THREAD_NUM];
int thread_num =0 ;
srand((time(NULL))); /*初始化随机数种子*/
pthread_mutex_init(&mutex,NULL);/*初始化互斥锁为快速互斥锁*/
/*创建线程*/
for( thread_num=0;thread_num < THREAD_NUM;thread_num ++)
{
if (pthread_create(&tid[thread_num],NULL,func_thread,(void *) thread_num) != 0)
{
printf("Create pthread[%d] failedn",thread_num);
exit(-1);
}
}
printf("Creat all thread sucessed,please waitting ...n" );
/*回收进程*/
for(thread_num = 0;thread_num <THREAD_NUM;thread_num++)
{
pthread_join(tid[thread_num],NULL);
printf("thread[%d] joinedn",thread_num);
}
pthread_mutex_destroy(&mutex); /*删除锁*/
exit(1);
}
结果对比
6.POISX信号量 System V 信号量参考此文
信号量实质是一个非负整数的计数器,是操作系统中的PV原语,常用于线程间的同步与互斥。
一次 P 操作使信号量sem 减 1, 而一次 V 操作使 sem 加 1。 进程( 线程) 根据信号量的值来判断是否对公共资源具有访问权限。当 sem 的值大于等于 0 时,该进程(或线程)具有公共资源的访问权限;相反,当 sem 的值小于 0 时,该进程(线程)就将阻塞直到 sem 的值大于等于 0 为止。
信号量常用语进程(线程)之间的同步或者互斥
互斥 当信号量作互斥作用时,往往设置一个信号量来决定资源归属
同步信号量做同步机制时,往往设置多个信号量,通过初始化值和PV操作来决定他们的运行顺序。
POSIX信号量相关API
信号量创建初始化函数 sem_init
信号量操作函数 PV操作、删除、获取信号量的值
**
7.POSIX信号量例程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define THREAD_NUM 3 /*线程数*/
#define TASKK_NUM 3 /*每个线程执行的小任务数*/
#define DELAY_TIME 10 /*每个小任务最大时间间隔*/
sem_t sem[THREAD_NUM];
/*线程函数*/
void * func_thread(void *arg)
{
int thread_num = (int) arg;
int delay_time = 0;
int count = 0;
/*每个线程首先进行P操作 ,判断有无资源*/
sem_wait(&sem[thread_num]);
printf("The thread [%d] is beginningn",thread_num);
for(count = 0; count<TASKK_NUM;count++)
{
delay_time =(int)(rand()%DELAY_TIME)+1; /*产生随机数1-DLY_TIME*/
sleep(delay_time);
printf("tthread[%d],job[%d],sleep[%d]sn",thread_num,count,delay_time);
}
printf("pthread[%d] endn",thread_num);
pthread_exit(NULL);
}
int main()
{
pthread_t tid[THREAD_NUM];
int thread_num =0 ;
srand((time(NULL))); /*初始化随机数种子*/
/*创建线程*/
for( thread_num=0;thread_num < THREAD_NUM;thread_num ++)
{
sem_init(&sem[thread_num],0,0);/*将所有信号量初始化为0*/
if (pthread_create(&tid[thread_num],NULL,func_thread,(void *) thread_num) != 0)
{
printf("Create pthread[%d] failedn",thread_num);
exit(-1);
}
}
/*将最后创建的一个进程进行V操作, sem[THREAD_NUM-1]变为1,最后创建的进程先运行*/
sem_post(&sem[THREAD_NUM-1]);
printf("Creat all thread sucessed,please waitting ...n" );
/*回收进程*/
for(thread_num = THREAD_NUM -1;thread_num >= 0;thread_num --)
{
pthread_join(tid[thread_num],NULL);
printf("thread[%d] joinedn",thread_num);
/*每回收一个线程就将下一个要运行线程解开,对上一个信号量V操作*/
sem_post(&sem[(thread_num+THREAD_NUM-1)%THREAD_NUM]);
}
/*删除信号量*/
for(thread_num = 0;thread_num <THREAD_NUM-1;thread_num++)
{
sem_destroy(&sem[thread_num]);
}
exit(1);
}
结果
最后
以上就是追寻篮球为你收集整理的Linux系统编程之线程控制及线程间同步互斥机制:POSIX信号量和互斥锁的全部内容,希望文章能够帮你解决Linux系统编程之线程控制及线程间同步互斥机制:POSIX信号量和互斥锁所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复