首页 > 系统相关 >20201317-Linux-Thread 互斥测试

20201317-Linux-Thread 互斥测试

时间:2022-11-10 09:23:28浏览次数:60  
标签:count Thread int lock 互斥 mutex pthread 线程 20201317

#include  <stdio.h>
#include  <stdlib.h>
#include  <pthread.h> //linux 线程库
#include  <ctype.h>   //测试和映射字符的库

struct arg_set {
		char *fname;
		int  count;
};//定义结构体

struct arg_set  *mailbox = NULL;//定义结构体指针;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//linux线程创建锁,初始化锁
pthread_cond_t  flag = PTHREAD_COND_INITIALIZER; //初始化条件变量,进行静态初始化

void *count_words(void *);//定义函数指针
int main(int argc, char *argv[])
{
	pthread_t t1, t2; //进行多线程管理
	struct arg_set args1, args2;//初始化两个结构体
	int reports_in = 0;
	int	total_words = 0;

	if ( argc != 3 ){
		printf("usage: %s file1 file2\n", argv[0]);
		exit(1);
	}//判断传入参量,参量的数量决定输出用法

	args1.fname = argv[1];//args1结构体指向第二个变量
	args1.count = 0;//args1结构体初始化count
	pthread_create(&t1, NULL, count_words, (void *) &args1);//在执行中创建一个线程, 为该线程分配它需要做的工作(线程执行函数), 该线程共享进程的资源

	args2.fname = argv[2];//args2结构体指向第三个变量
	args2.count = 0;//args2结构体count初始化
	pthread_create(&t2, NULL, count_words, (void *) &args2);//创建线程,并分配需要做的工作和资源,分配共享进程的资源

	pthread_mutex_lock(&lock);//加锁
	while( reports_in < 2 ){
		printf("MAIN: waiting for flag to go up\n");
		pthread_cond_wait(&flag, &lock);//阻塞当前线程,等待别的线程使用 
		printf("MAIN: Wow! flag was raised, I have the lock\n");
		printf("%7d: %s\n", mailbox->count, mailbox->fname);
		total_words += mailbox->count;//加mailbox的count值
		if ( mailbox == &args1) 
			pthread_join(t1,NULL);
        //阻塞调用它的线程,直至目标线程执行结束
		if ( mailbox == &args2) 
			pthread_join(t2,NULL);
		mailbox = NULL;
		pthread_cond_signal(&flag);	
        //发送一个信号,给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态
		reports_in++;
	}
	pthread_mutex_unlock(&lock);
	//解除锁定mutex所指向的互斥锁的函数
	printf("%7d: total words\n", total_words);
}
void *count_words(void *a)
{
	struct arg_set *args = a;
    //初始化结构体,指向传参a;
	FILE *fp;
	int  c, prevc = '\0';
	
	if ( (fp = fopen(args->fname, "r")) != NULL ){
        //成功打开文件
        
		while( ( c = getc(fp)) != EOF ){
			if ( !isalnum(c) && isalnum(prevc) )
                //isalnum检测字符串是否由字母和数字组成。
				args->count++;
                //指向的数值count增加1
			prevc = c;
            
		}
		fclose(fp);
	} else 
		perror(args->fname);
	printf("COUNT: waiting to get lock\n");
	pthread_mutex_lock(&lock);//上锁	
	printf("COUNT: have lock, storing data\n");
	if ( mailbox != NULL ){
		printf("COUNT: oops..mailbox not empty. wait for signal\n");
		pthread_cond_wait(&flag,&lock);
	}
	mailbox = args;			
	printf("COUNT: raising flag\n");
	pthread_cond_signal(&flag);	
	printf("COUNT: unlocking box\n");
	pthread_mutex_unlock(&lock);	
	return NULL;
}

在线程实际运行过程中,我们经常需要多个线程保持同步。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock这几个函数以完成锁的初始化,锁的销毁,上锁和释放锁操作。

一,锁的创建

锁可以被动态或静态创建,可以用宏PTHREAD_MUTEX_INITIALIZER来静态的初始化锁,采用这种方式比较容易理解,互斥锁是pthread_mutex_t的结构体,而这个宏是一个结构常量,如下可以完成静态的初始化锁:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

另外锁可以用pthread_mutex_init函数动态的创建,函数原型如下:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr)

二,锁的属性

互斥锁属性可以由pthread_mutexattr_init(pthread_mutexattr_t *mattr);来初始化,然后可以调用其他的属性设置方法来设置其属性;

互斥锁的范围:可以指定是该进程与其他进程的同步还是同一进程内不同的线程之间的同步。可以设置为PTHREAD_PROCESS_SHARE和PTHREAD_PROCESS_PRIVATE。默认是后者,表示进程内使用锁。可以使用int pthread_mutexattr_setpshared(pthread_mutexattr_t *mattr, int pshared)

pthread_mutexattr_getshared(pthread_mutexattr_t *mattr,int *pshared)

用来设置与获取锁的范围;

互斥锁的类型:有以下几个取值空间:

  PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

  PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

  PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

  PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。

可以用
pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)

获取或设置锁的类型。

三,锁的释放

调用pthread_mutex_destory之后,可以释放锁占用的资源,但这有一个前提上锁当前是没有被锁的状态。

四,锁操作

对锁的操作主要包括加锁 pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个。

  int pthread_mutex_lock(pthread_mutex_t *mutex)

  int pthread_mutex_unlock(pthread_mutex_t *mutex)

  int pthread_mutex_trylock(pthread_mutex_t *mutex)

  pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待

image-20221110091120183

image-20221110091136451

image-20221110091100337

标签:count,Thread,int,lock,互斥,mutex,pthread,线程,20201317
From: https://www.cnblogs.com/lyxhhz/p/16875953.html

相关文章

  • 性能爆表:利用ThreadPoolTaskExecutor批量插入百万级数据实测!
    来源:azdebug.blog.csdn.net/article/details/103697108前言开发目的:提高百万级数据插入效率。采取方案:利用ThreadPoolTaskExecutor多线程批量插入。采用技术:spring......
  • Java并发编程一ThreadLocal初使用
    推荐:​​Java并发编程汇总​​Java并发编程一ThreadLocal初使用任务为了方便使用以及展现​​ThreadLocal​​​的优点,这里首先给出一个任务,然后不断地去加大任务难度,再根据......
  • thread同步
    一、实验截图修改前修改后二、实验代码//更改前#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<semaphore.h>#defineNUM5intqueu......
  • thread同步测试
    thread同步测试任务1编译运行附件中的代码,提交运行结果截图,并说明程序功能2修改代码,把同步资源个数减少为3个,把使用资源的线程增加到(你的学号%3+4)个,编译代码,提交修......
  • thread互斥测试
    thread互斥测试#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<ctype.h>structarg_set{ char*fname; intcount;};structarg......
  • Java中线程的基本操作以及Thread和Runnable两种实现的比较
    线程的定义:某一时间点执行的处理,是操作系统能够进行运算调度的最小单位。一条线程是某一进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务......
  • thread互斥测试
    题目要求编译运行附件中的代码,并说明程序的功能根据自己的理解,提交不少于3张图片代码#include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<ct......
  • thread同步测试
    thread同步测试#include<stdio.h>#include<pthread.h>#include<stdlib.h>#include<semaphore.h>#defineNUM5intqueue[NUM];sem_tblank_number,product_nu......
  • thread同步测试
    任务说明1.编译运行附件中的代码,提交运行结果截图,并说明程序功能2.修改代码,把同步资源个数减少为3个,把使用资源的线程增加到(你的学号%3+4)个,编译代码,提交修改后的代码......
  • thread同步测试
    题目1编译运行附件中的代码,提交运行结果截图,并说明程序功能2修改代码,把同步资源个数减少为3个,把使用资源的线程增加到(你的学号%3+4)个,编译代码,提交修改后的代码和运......