linux 线程属性控制

本节主要讲 pthread_create 函数的第二个参数——线程的属性。之前设为 NULL,也就是采用默认属性。现在讲一下修改线程属性的方法。
这些属性主要包括绑定属性、分离属性、堆栈地址、堆栈大小、优先级。其中系统默认的属性为非绑定、非分离、缺省1M 的堆栈、与父进程同样级别的优先级。
具体属性的含义请参考手册,本文只讲如何使用这些函数。其实挺简单的,
跟普通的线程调用只需多加三步:
1、调用pthread_attr_init初始化线程属性。
2、调用相应的设置属性的函数,如下文用到的pthread_attr_setschedparam设置线程优先级。
3、然后将pthread_create的第二个参数传进去。

来看看设置线程属性的一些相关函数:

pthread_attr_init函数:

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr)

返回值:若成功,返回0;若出错,返回-1
参数:

  • attr:线程属性

pthread_attr_setscope函数:

#include <pthread.h>
int pthread_attr_setscope(pthread_attr_t *attr, int scope)

返回值:若成功,返回0;若出错,返回-1
参数:

  • attr:线程属性
  • scope
    • PTHREAD_SCOPE_SYSTEM:绑定
    • PTHREAD_SCOPE_PROCESS:非绑定

pthread_attr_setdetachstate函数:

#include <pthread.h>
int pthread_attr_setscope(pthread_attr_t *attr, int detachstate)

返回值:若成功,返回0;若出错,返回-1
参数:

  • attr:线程属性
  • detachstate:
    • PTHREAD_CREATE_DETACHED:分离
    • PTHREAD _CREATE_JOINABLE:非分离

pthread_attr_getschedparam函数:

#include <pthread.h>
int pthread_attr_getschedparam (pthread_attr_t *attr, struct sched_param *param)

返回值:若成功,返回0;若出错,返回-1
参数:

  • attr:线程属性
  • param:线程优先级

pthread_attr_setschedparam函数:

#include <pthread.h>
int pthread_attr_setschedparam (pthread_attr_t *attr, struct sched_param *param)

返回值:若成功,返回0;若出错,返回-1
参数:

  • attr:线程属性
  • param:线程优先级

示例程序:

主要看看线程属性是如何使用的。

/* pthread_attr_control.c*/

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <semaphore.h>
#include <sched.h>
#include <assert.h>

sem_t sem;
static int count = 0 ;
#define FILENAME "pthread_attr_control_file"
/*线程一*/
void thread1(void * arg)
{
    char write_buf[] = "1";
    int fd = *(int *)arg;
    printf("this is pthread1,fd = %d\n",fd);
    int i = 0;
    while(1)
    {
        /*信号量减一,P 操作*/
        sem_wait(&sem);
        for(i = 0;i<5;i++)
        {
            if (write(fd,write_buf,sizeof(write_buf)))
            {
                perror("write");
            }
            count++;
        }
        printf("This is a pthread1....and count = %d\n",count);
        /*信号量加一,V 操作*/
        sem_post(&sem);
        sleep(2);
    }
}
/*线程二*/
void thread2(void * arg)
{
    char write_buf[] = "2";
    int fd = *(int *)arg;
    printf("this is pthread2 and fd = %d\n",fd);
    int i = 0;
    while(1)
    {
        /*信号量减一,P 操作*/
        sem_wait(&sem);
        for(i = 0;i<5;i++)
        {
            if (write(fd,write_buf,sizeof(write_buf)))
            {
                perror("write");
            }       
            count++;
        }

        printf("This is a pthread2.... count = %d\n",count);    
        /*信号量加一,V 操作*/
        sem_post(&sem);
        sleep(2);
    }
}

static int api_get_thread_policy (pthread_attr_t *attr)
{
    int policy;
    int rs = pthread_attr_getschedpolicy (attr, &policy);
    assert (rs == 0);

    switch (policy)
    {
        case SCHED_FIFO:
            printf ("policy = SCHED_FIFO\n");
            break;
        case SCHED_RR:
            printf ("policy = SCHED_RR");
            break;
        case SCHED_OTHER:
            printf ("policy = SCHED_OTHER\n");
            break;
        default:
            printf ("policy = UNKNOWN\n");
            break; 
    }
    return policy;
}
int main(void)
{
    int fd = open(FILENAME,O_RDWR | O_CREAT,0777);
    if(fd < 0)
    {
        perror("open");
    }
    printf("open success!\n");
    int i,ret;
    /*初始化信号量为 1*/
    ret=sem_init(&sem,0,1);
    if(ret!=0)
    {
        perror("sem_init");
    }

    pthread_t id1,id2;
    pthread_attr_t attr;
    //获取线程调度优先级
    struct sched_param param;
    int rs = pthread_attr_getschedparam (&attr, &param);
    assert (rs == 0);
    printf ("current priority = %d\n", param.__sched_priority);

    /* 获得当前调度策略 */
    int policy = api_get_thread_policy (&attr);

    int priority_max = sched_get_priority_max (policy);
    assert (priority_max != -1);
    printf ("max_priority = %d\n", priority_max);

    int priority_min = sched_get_priority_min (policy);
    assert (priority_min != -1);
    printf ("min_priority = %d\n", priority_min);
    int priority = priority_min + 1;
    printf("the priority of pthread1 is %d",priority);
    /*初始化线程属性*/
    pthread_attr_init(&attr);
    //设置线程一优先级
    rs = pthread_attr_setschedpolicy (&attr, priority);
    assert (rs == 0);

//  rs = pthread_attr_getschedparam (&attr, &param);
//  assert (rs == 0);
//  printf ("show show ------priority = %d\n", param.__sched_priority);

    /*创建线程一*/
    ret=pthread_create(&id1,&attr,(void *) thread1,&fd);
    if(ret!=0){
    perror("Create pthread error!\n");
    }
    //设置线程二优先级
    priority = priority_min;
    printf("the priority of pthread1 is %d",priority);
    rs = pthread_attr_setschedpolicy (&attr, priority);
    assert (rs == 0);
    /*创建线程二*/
    ret=pthread_create(&id2,&attr,(void *) thread2,&fd);
    if(ret!=0){
    perror ("Create pthread error!\n");
    }

    /*等待线程结束*/
    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    return 0;
}

实验结果:

ubuntu:~/test/pthread_test$ gcc pthread_attr_control.c -o pthread_attr_control -lpthread
ubuntu:~/test/pthread_test$ ./pthread_attr_control                                      
open success!
current priority = 0
policy = SCHED_OTHER
max_priority = 0
min_priority = 0
the priority of pthread1 is 1the priority of pthread1 is 0this is pthread2 and fd = 3
this is pthread1,fd = 3
write: Success
write: Success
write: Success
write: Success
write: Success
This is a pthread2.... count = 5
write: Success
write: Success
write: Success
write: Success
write: Success
This is a pthread1....and count = 10
write: Success
write: Success
write: Success
write: Success
write: Success
This is a pthread2.... count = 15
write: Success
write: Success
write: Success
write: Success
write: Success
This is a pthread1....and count = 20
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值