Linux编程基础之多线程编程(二)

上一文中简单的说了一下Linux多线程编程的基本操作,这一文来简单的说一说线程之间的同步和互斥。首先说一下多线程之间同步和互斥的基本概念和操作,然后编写一个小例子进行测试。

一、基本概念和操作

由于线程之间对资源和存储空间是共享的,因此对这些资源进行操作和访问时,必须考虑多线程之间的同步和互斥问题。在POSIX中有两种线程的同步机制:互斥锁和信号量。互斥锁比较适用于同时可用资源是唯一的情况,而信号量更适用于同时可用资源为多个的情况。本文重点来说一下互斥锁的使用。

互斥锁常用API说明:

a、初始化一个互斥锁

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
        mutex : 创建一个互斥锁的标识

        mutexattr : 创建的互斥锁的属性,主要有三种,分别是: PTHREAD_MUTEX_INITIALIZER,创建快速互斥锁;PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,创建递归互斥锁;PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP,创建检错互斥锁。默认为快速互斥锁。

        返回值:0成功,出错返回错误码

b、其他API函数

int pthread_mutex_lock(pthread_mutex_t *mutex,)		// 互斥锁上锁
int pthread_mutex_trylock(pthread_mutex_t *mutex,)	// 互斥锁判断上锁
int pthread_mutex_unlock(pthread_mutex_t *mutex,)	// 互斥锁解锁
int pthread_mutex_destroy(pthread_mutex_t *mutex,)	// 销毁互斥锁
        mutex :要操作的互斥锁的标识

        返回值:0 成功,出错返回错误码。

二、测试

编写一个测试的小例子,实现的功能是:在主线程中创建两个子线程,当其中一个子线程运行完毕时,另一个子线程才开始运行。具体的代码实现如下所示:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

/* 定义一个全局变量用于定义互斥锁 */
static pthread_mutex_t mutex;

/*
 *	子线程a的线程体
 */
static void *start_routine_a (void *arg)
{
	int loop_cnt = (int)arg;
	int i;

	pthread_mutex_lock(&mutex);		// 进程A上锁

	printf("thread A : start!\n");

	for(i = 0; i < 5; i++)
	{
		printf("TECH-PRO thread A : %d\n", i);
		sleep(1);
	}

	printf("thread A : stop!\n");

	pthread_mutex_unlock(&mutex);	// 进程A释放锁

	pthread_exit(NULL);		/* 线程执行完毕 */
}

/*
 *	子线程b的线程体
 */
static void *start_routine_b (void *arg)
{
	int loop_cnt = (int)arg;
	int i;

	pthread_mutex_lock(&mutex);		// 进程B上锁

	printf("thread B : start!\n");

	for(i = 0; i < 5; i++)
	{
		printf("TECH-PRO thread B : %d\n", i);
		sleep(1);
	}

	printf("thread B : stop!\n");

	pthread_mutex_unlock(&mutex);	// 进程B释放锁

	pthread_exit(NULL);		/* 线程执行完毕 */
}


/*
 *	定义两个子线程,让两个子线程同时运行
 */
int main(void)
{
	int ret;
	pthread_t pthread_a, pthread_b;

	/* 初始化这个互斥锁 */
	ret = pthread_mutex_init(&mutex, NULL);
	if(0 != ret)
	{
		printf("pthread_mutex_init error!\n");
		return -1;
	}

	/* 开始 */
	printf("main : start!\n");

	/* 创建两个子线程 */
	ret = pthread_create(&pthread_a, NULL, start_routine_a, (void *)5);
	if(0 != ret)
	{
		printf("pthread_create for a is failed!\n");
		return -1;
	}

	ret = pthread_create(&pthread_b, NULL, start_routine_b, (void *)5);
	if(0 != ret)
	{
		printf("pthread_create for b is failed!\n");
		return -1;
	}

	/* 等待进程结束 */
	pthread_join(pthread_a, NULL);
	pthread_join(pthread_b, NULL);

	/* 结束 */
	printf("main : stop!\n");

	pthread_mutex_destroy(&mutex);	// 销毁互斥锁

	return 0;
}
对程序进行编译,注意编译和链接时要加上-lpthread,运行结果如下:

从运行结果中可以看出,A线程先运行,等A线程运行结束后B线程才开始运行。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值