threads5 互斥信号量type

互斥信号量is互斥量by short
互斥量的类型

/**********/usr/include/pthread.h**********
 Mutex types.  
*/
enum
{
  PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_ADAPTIVE_NP
#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
  ,
  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
  /* For compatibility.  */
  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};
/*
/usr/include/bits/pthreadtype.h********
pthread_mutex_t
*/
typedef union
{
  struct
  {
    int __lock;
    unsigned int __nr_readers;
    unsigned int __readers_wakeup;
    unsigned int __writer_wakeup;
    unsigned int __nr_readers_queued;
    unsigned int __nr_writers_queued;
    /* FLAGS must stay at this position in the structure to maintain
       binary compatibility.  */
    unsigned char __flags;
    unsigned char __shared;
    unsigned char __pad1;
    unsigned char __pad2;
    int __writer;
  } __data;
  char __size[__SIZEOF_PTHREAD_RWLOCK_T];
  long int __align;
} pthread_rwlock_t;
*PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。
当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
*PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,
允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
*PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,
如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。
这样就保证当步允许多次加锁 时不会出现最简单情况下的死锁。
*PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,
动作最简单的锁类型,仅等待解锁后重新竞争。

a线程可解b线程的普通锁,如下
[root@localhost ch12]# cat thread4.c 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>


void *thread_function(void *arg);
pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */
pthread_mutexattr_t attr; 
#define WORK_SIZE 1024
char work_area[WORK_SIZE];

int main() {
	int res;
	pthread_t a_thread;
	void *thread_result;

	if((res=pthread_mutexattr_init(&attr))!=0) 
	perror("pthread_mutexattr_init error");
	if((res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL))!=0)
	perror("pthread_mutexattr_settype error");

	if((res= pthread_mutex_init(&work_mutex, &attr))!=0) 
	perror("pthread_mutexattr_init error");

	res = pthread_create(&a_thread, NULL, thread_function, NULL);
	if (res != 0) {
	perror("Thread creation failed");
	exit(EXIT_FAILURE);
	}


	//lock
	printf("work_mutex in main_1:%d\n",work_mutex);
	res=pthread_mutex_lock(&work_mutex);
	printf("main1res_1:%d\n",res);
	printf("work_mutex in main_2:%d\n",work_mutex);

	printf("------------Waiting for thread to finish------------\n");
	res = pthread_join(a_thread, &thread_result);
	if (res != 0) {
		perror("Thread join failed");
		exit(EXIT_FAILURE);
	}
	printf("Thread joined\n");
	pthread_mutex_destroy(&work_mutex);
	printf("sleep(120)\n");
	sleep(120);
	exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) 
{
	int res;
	printf("hello_1\n");

	printf("work_mutex in sub_1:%d\n",work_mutex);
	res=pthread_mutex_unlock(&work_mutex);
	printf("subres_1:%d\n",res);
	printf("work_mutex in sub_2:%d\n",work_mutex);

	printf("hello_2\n");
}
[root@localhost ch12]# make
cc -D_REENTRANT  -lpthread  thread4.c   -o thread4
[root@localhost ch12]# ./thread4
work_mutex in main_1:0
main1res_1:0
work_mutex in main_2:1
------------Waiting for thread to finish------------
hello_1
work_mutex in sub_1:1
subres_1:0
work_mutex in sub_2:0
hello_2
Thread joined
sleep(120)


 上面的printf("%d\n",work_mutex);  打印结果是当前work_mutex的上锁次数,普通锁此值最大为1
子线程解对主线程的锁,返回值0,说明成功解锁,执行结果也验证le这一点

已经知道,b线程欲对a线程已经上过的普通锁进行上锁,则b线程会被阻塞
a线程本身对普通锁多次上锁的的话,会怎么样呢
[root@localhost ch12]# cat thread4.c 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>


void *thread_function(void *arg);
pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */
pthread_mutexattr_t attr; 
#define WORK_SIZE 1024
char work_area[WORK_SIZE];

int main() {
	int res;
	pthread_t a_thread;
	void *thread_result;

	if((res=pthread_mutexattr_init(&attr))!=0) 
	perror("pthread_mutexattr_init error");
	if((res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL))!=0)//mutex type
	perror("pthread_mutexattr_settype error");

	if((res= pthread_mutex_init(&work_mutex, &attr))!=0) 
	perror("pthread_mutexattr_init error"); 

        res = pthread_create(&a_thread, NULL, thread_function, NULL);
	if (res != 0) {
	perror("Thread creation failed");
	exit(EXIT_FAILURE);
	} 

	//lock
	printf("work_mutex in main_1:%d\n",work_mutex);
	res=pthread_mutex_lock(&work_mutex);
	printf("main1res_1:%d\n",res);
	printf("work_mutex in main_2:%d\n",work_mutex);
	//lock again

	res=pthread_mutex_lock(&work_mutex);
	printf("main1res_1:%d\n",res);
	printf("work_mutex in main_2:%d\n",work_mutex);

	printf("------------Waiting for thread to finish------------\n");
	res = pthread_join(a_thread, &thread_result);
	if (res != 0) {
		perror("Thread join failed");
		exit(EXIT_FAILURE);
	}
	printf("Thread joined\n");
	pthread_mutex_destroy(&work_mutex);
	printf("sleep(120)\n");
	sleep(120);
	exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) 
{
/*	int res;
	printf("hello_1\n");

	printf("work_mutex in sub_1:%d\n",work_mutex);
	res=pthread_mutex_unlock(&work_mutex);
	printf("subres_1:%d\n",res);
	printf("work_mutex in sub_2:%d\n",work_mutex);

	printf("hello_2\n");
*/}

[root@localhost ch12]# ./thread4
work_mutex in main_1:0
main1res_1:0
work_mutex in main_2:1


结果是形成死锁------须在第二次上锁之前先解锁
可以自己解,也可以其他线程解
看来普通锁面对本线程or其他线程,都是一个态度

将上面的普通锁换成检错锁,即line22改为
	if((res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK))!=0)//mutex type

结果是,
第二次上锁时没被阻塞,而是返回一个35的错误代码

[root@localhost ch12]# ./thread4
work_mutex in main_1:0
main1res_1:0
work_mutex in main_2:1
main1res_1:35
work_mutex in main_2:1
------------Waiting for thread to finish------------
Thread joined
sleep(120)

将上面的普通锁换成嵌套锁,即line22改为RECURSIVE,并修改程序如下
[root@localhost ch12]# cat thread4.c 
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <string.h>  
#include <pthread.h>  
  
  
void *thread_function(void *arg);  
pthread_mutex_t work_mutex; /* protects both work_area and time_to_exit */  
pthread_mutexattr_t attr;   
#define WORK_SIZE 1024  
char work_area[WORK_SIZE];  
  
int main() {  
    int res;  
    pthread_t a_thread;  
    void *thread_result;  
  
    if((res=pthread_mutexattr_init(&attr))!=0)   
    perror("pthread_mutexattr_init error");  
    if((res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE))!=0)//mutex type  
    perror("pthread_mutexattr_settype error");  
  
    if((res= pthread_mutex_init(&work_mutex, &attr))!=0)   
    perror("pthread_mutexattr_init error");   
  
        res = pthread_create(&a_thread, NULL, thread_function, NULL);  
    if (res != 0) {  
    perror("Thread creation failed");  
    exit(EXIT_FAILURE);  
    }   
  
    //lock  
    printf("work_mutex in main_1:%d\n",work_mutex);  
    res=pthread_mutex_lock(&work_mutex);  
    printf("main1res_1:%d\n",res);  
    printf("work_mutex in main_2:%d\n",work_mutex);  
    //lock again  
  
    res=pthread_mutex_lock(&work_mutex);  
    printf("main1res_1:%d\n",res);  
    printf("work_mutex in main_2:%d\n",work_mutex);  
  
    printf("------------Waiting for thread to finish------------\n");  
    res = pthread_join(a_thread, &thread_result);  
    if (res != 0) {  
        perror("Thread join failed");  
        exit(EXIT_FAILURE);  
    }  
    printf("Thread joined\n");  
    pthread_mutex_destroy(&work_mutex);  
    printf("sleep(120)\n");  
    sleep(120);  
    exit(EXIT_SUCCESS);  
}  
  
void *thread_function(void *arg)   
{  
  int res; 
    printf("hello_1\n"); 
 
    printf("work_mutex in sub_1:%d\n",work_mutex); 
    res=pthread_mutex_lock(&work_mutex); 
    printf("subres_1:%d\n",res); 
    printf("work_mutex in sub_2:%d\n",work_mutex); 
 
    printf("hello_2\n"); 
}  
[root@localhost ch12]# ./thread4
work_mutex in main_1:0
main1res_1:0
work_mutex in main_2:1
main1res_1:0
work_mutex in main_2:1
------------Waiting for thread to finish------------
hello_1
work_mutex in sub_1:1


可见主线程中在解锁之前多次加锁均不会阻塞,但在子线程中加锁却被阻塞
另外,
子线程解不开主线程上的锁
主线程加了几次锁,就要释放几次锁,否则子线程永远得不到此锁而一直阻塞
貌似嵌套锁就是用来帮第一个上锁者占茅坑的
本来认为printf("%d\n",work_mutex);  打印结果是当前work_mutex的上锁次数
但是即使是用嵌套锁试验,只是偶尔可以打印出2
不知为何,先放着哈。
从以上也可看出,sleep是用来阻塞的并且阻塞的是当前线程,不是进程

apue2中列出了各种情况下操作锁的反应,不过有些结果与我试验de不一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值