Linux C 线程间同步机制

概述

  同进程内的所有线程共同使用进程的内存空间,并且线程可以在直接应用层完成,因此线程和线程之间的通信使用“全局变量”即可完成通信。但是由于 Linux 系统没有数据保护方式,所在在线程通信的时候需要进行数据的“同步保护”。
  在同进程中的多个线程都要操作的数据进行保护时,只允许一个线程操作要保护的内容。Linux 系统使用“信号量”、“互斥锁”以及“条件变量”来实现数据同步保护。实现数据保护的流程为:
①创建一种使用的保护机制(信号量、互斥锁或条件变量)。
②在操作保护内容之前,加保护(一旦本线程加保护成功,其他线程在操作就会阻塞)。
③在操作保护内容后,解保护(其他线程自动取消阻塞)。
④删除保护机制。
注:线程间的数据保护机制是一种人为的约束,一定要所有线程都要遵循这个操作才会有意义,同时“加保护”、“解保护”操作在一个线程中一定要成对出现。

保护机制

互斥锁

创建互斥锁  pthread_mutex_init

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数介绍:
  mutex:互斥锁编号。
  attr:互斥锁的属性。
在这里插入图片描述
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_t mutexid;
	pthread_mutex_init(&mutexid,NULL);

加锁  pthread_mutex_lock

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_lock(&mutexid);

解锁  pthread_mutex_unlock

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_unlock(&mutexid);

删除锁  pthread_mutex_destroy

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_destroy(pthread_mutex_t *mutex)
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_destroy(&mutexid);

条件变量

创建条件变量  pthread_cond_init

头文件
  #include <pthread.h>
函数原型:int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_t condid;
	pthread_cond_init(&condid,NULL);

激活条件变量  pthread_cond_signal

头文件
  #include <pthread.h>
函数原型:int pthread_cond_signal(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_signal(&condid);

等待条件变量  pthread_cond_wait

头文件
  #include <pthread.h>
函数原型:int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_wait(&condid,&mutexid);

删除条件变量  pthread_cond_destroy

头文件
  #include <pthread.h>
函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_destroy(&condid);

信号灯

创建信号量  sem_init

头文件
  #include <semaphore.h>
函数原型:==int sem_init(sem_t *sem, int pshared, unsigned int value); ==
参数介绍:
  sem:信号量编号。
  pshared:信号量在作用范围(0:本进程中多个线程共享可用;非 0:在当前登录用户的多个进程之间共享)。
  value:信号量的信号值。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_t semid;
	sem_init(&semid,0, 1);

信号量加保护  sem_wait

头文件
  #include <semaphore.h>
函数原型:int sem_wait(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_wait(&semid);

信号量解保护  sem_post

头文件
  #include <semaphore.h>
函数原型:int sem_post(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_post(&semid);

信号量删除  sem_destroy

头文件
  #include <semaphore.h>
函数原型:int sem_destroy(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_destroy(&semid);

线程间通信的例子

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
char path[10];
//信号服务函数
void * son_fun(void * arg)
{
	int fd2 = open(path,O_RDWR);		//打开读管道
	while(1)
	{
		char rb[512] = {0};
		read(fd2,rb,sizeof(rb));	
		printf("%s说:%s\n",(char *)arg,rb);	
	}
	close(fd2);							//关闭读管道
}
//关于argv:
// 1 是读通道  2 是写通道  3 是自己的信号  4 是发的信号
int main(int argc,char *argv[])
{
	//init
	pthread_t id;
	strcpy(path,argv[2]);
	//创建管道
	int val1 = mkfifo(argv[1],0666);
	int val2 = mkfifo(argv[2],0666);
	//打开管道
	int fd1 = open(argv[1],O_RDWR); 		//写管道
	//创建子线程
	pthread_create(&id,NULL,son_fun,"he say");//创建子线程
	//等待写入
	while(1)
	{
		char wb[512] = {0};
		gets(wb);
		write(fd1,wb,strlen(wb));
	}
	close(fd1);
	pthread_join(id,NULL);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值