unix内核对象属性

unix中,线程(pthread),互斥锁(mutex),读写锁(rwlock),条件变量(cond)等他们都有一组属性,且功能类似。

他们通用的规则如下:

1.每个对象与其对应的属性对象相关联,通常属性对象对应用程序是不透明的,它提供了一组接口操作属性对象。

2.init函数对属性对象初始化,分配资源

3.destory函数销毁属性对象,回收资源

4.get函数获取属性值

5.set函数设置属性

一:线程属性:

int pthread_attr_init(pthread_attr_t *attr); 

int pthread_attr_destroy(pthread_attr_t *attr);

detachstate:表示该线程结束后,线程资源会自动被操作系统回收,其他线程不能pthread_join该线程。

int pthread_attr_getdetachstate(const pthread_attr_t *attr,int *detachstate);

int pthread_attr_setdetachstate(cost pthread_attr_t *attr,int *detachstate);

//detachstate的取值为PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE

#include <pthread.h>

int makethread(void *(*fn)(void *), void *arg)
{
	int				err;
	pthread_t		tid;
	pthread_attr_t	attr;

	err = pthread_attr_init(&attr);
	if (err != 0)
		return(err);
	err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (err == 0)
		err = pthread_create(&tid, &attr, fn, arg);
	pthread_attr_destroy(&attr);
	return(err);
}

线程栈地址属性stackaddr:

int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr, size_t stacksize);

int pthread_attr_getstack(pthread_attr_t *attr,void **stackaddr, size_t *stacksize);

线程栈大小属性stacksize:

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

线程栈之后避免栈溢出的警戒缓冲区大小属性guardsize:

int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);

二:互斥锁(mutex)属性

1.初始化和销毁

       int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
       int pthread_mutexattr_init(pthread_mutexattr_t *attr);
       PTHREAD_MUTEX_INITIALIZER//对于静态属性类型的初始化

2.获取/设置进程共享属性:可设置的值PTHREAD_PROCESS_PRIVATE/PTHREAD_PROCESS_SHARED

       int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared);
       int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);

3.获取/设置拥有锁的线程退出后,是否被通知的属性:可设置的值
PTHREAD_MUTEX_STALLED:拥有锁的线程退出后,若未解锁,则继续拥有,其他线程加锁操作会被阻塞,可能导致死锁
PTHREAD_MUTEX_ROBUST:拥有锁的线程退出后,若未解锁,则继续拥有,其他加锁操作阻塞的线程会被通知,出错返回,返回值为EOWNERDEAD,其他线程如果想继续使用该互斥锁,则必须先调用pthread_mutex_consistent,然后调用 pthread_mutex_unlock.然后该锁就可以被继续使用,对lock操作返回值为EOWNERDEAD的锁,如果没有调用pthread_mutex_consistent,那么对该锁唯一合法的操作是使用destroy。

       int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust);
       int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr,int robust);
       int pthread_mutex_consistent(pthread_mutex_t *mutex);

4.获取/设置互斥锁类型属性:PTHREAD_MUTEX_NORMAL(标准互斥锁)/PTHREAD_MUTEX_ERRORCHECK(提供错误检查)
PTHREAD_MUTEX_RECURSIVE(递归互斥锁,可加锁多次)/PTHREAD_MUTEX_DEFAULT(默认锁)

       int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
       int pthread_mutexattr_settype(pthread_mutexattr_t *attr,int type);

三:读写锁(rwlock)属性

1.初始化和销毁

       int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
       int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
       PTHREAD_RWLOCK_INITIALIZER//对于静态属性类型的初始化

2.获取/设置进程共享属性:可设置的值PTHREAD_PROCESS_PRIVATE/PTHREAD_PROCESS_SHARED

       int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared);
       int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared);

四:条件变量属性

1.初始化和销毁

       int pthread_condattr_destroy(pthread_condattr_t *attr);
       int pthread_condattr_init(pthread_condattr_t *attr);
       PTHREAD_COND_INITIALIZER//对于静态属性类型的初始化

2.获取/设置进程共享属性:可设置的值PTHREAD_PROCESS_PRIVATE/PTHREAD_PROCESS_SHARED

       int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared);
       int pthread_condattr_setpshared(pthread_condattr_t *attr,int pshared);

五:屏障属性

1.初始化和销毁

       int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
       int pthread_barrierattr_init(pthread_barrierattr_t *attr);

2.获取/设置进程共享属性:可设置的值PTHREAD_PROCESS_PRIVATE/PTHREAD_PROCESS_SHARED

       int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared);
       int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);

 

以下代码段给出初始化一个互斥锁,以便他能在进程间共享属性的过程:

pthread_mutex_t           *pmutex;
pthread_mutexattr_t       mutexattr;
pmutex=/*some value that points to shared memory,使互斥锁指针指向共享内存区*/
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);
pthread_mutex_init(pmutex,&mutexattr);
pthread_mutexattr_destory(&mutexattr);

下面是一个简单的demo

/*
    互斥量 实现 多进程 之间的同步 
*/
 
#include<unistd.h>
#include<sys/mman.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
 
struct mt
{
    int num;
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
};
 
 
int main(void)
{
    
    int i;
    struct mt* mm;
 
    pid_t pid;
 
    /*
    // 创建映射区文件
    int fd = open("mt_test",O_CREAT|O_RDWR,0777);
    if( fd == -1 ) 
    {
        perror("open file:"); 
        exit(1); 
    }
    ftruncate(fd,sizeof(*mm));
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    close(fd);
    unlink("mt_test");
  */
 
    // 建立映射区
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
 
//    printf("-------before memset------\n");
    memset(mm,0x00,sizeof(*mm));
//   printf("-------after memset------\n");
 
    pthread_mutexattr_init(&mm->mutexattr);         // 初始化 mutex 属性
    pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED);               // 修改属性为进程间共享
 
    pthread_mutex_init(&mm->mutex,&mm->mutexattr);      // 初始化一把 mutex 锁
    
    pid = fork();
    if( pid == 0 )          // 子进程
    {
        for( i=0; i<10;i++ )
        {
            pthread_mutex_lock(&mm->mutex);
            (mm->num)++;
            printf("-child--------------num++    %d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
            sleep(1);
        }
    
    }
    else 
    {
        for( i=0;i<10;i++)
        {
            sleep(1); 
            pthread_mutex_lock(&mm->mutex);
            mm->num += 2;
            printf("--------parent------num+=2   %d\n",mm->num);
            pthread_mutex_unlock(&mm->mutex);
        
        }
        wait(NULL);
 
    }
    pthread_mutexattr_destroy(&mm->mutexattr);  // 销毁 mutex 属性对象
    pthread_mutex_destroy(&mm->mutex);          // 销毁 mutex 锁
 
    return 0;
}

       void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);

要理解这个函数请看下图,该函数是将fd指定的文件映射到addr为起始地址的共享内存中,offset为文件偏移量,length为映射长度,通常我们指定addr为NULL,它表示内核会为我们分配内存,我们不必关心内存具体的起始地址,返回值指向这个起始地址。该函数的fd=-1,表示分配一块匿名的共享内存区,互斥锁必须存储在共享内存区中才能应用于进程间的同步。


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值