首页 > 代码库 > POSIX线程(2)

POSIX线程(2)

线程属性
初始化与销毁属性
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
获取与设置分离属性
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
获取与设置栈大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

获取与设置栈溢出保护区大小
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
获取与设置线程竞争范围
int pthread_attr_getscope(const pthread_attr_t *attr,int *contentionscope);
int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
获取与设置调度策略
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

获取与设置继承的调度策略
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
获取与设置调度参数
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);


并发级别

获取与设置并发级别
int pthread_setconcurrency(int new_level);
int pthread_getconcurrency(void);
仅在N:M线程模型中有效,设置并发级别,给内核一个提提示:表示提供给定级别数量的核心线程来映射用户线程是高效的。

线程特定数据
在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。
在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。
但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问。
POSIX线程库通过维护一定的数据结构来解决这个问题,这个些数据称为(Thread-specific Data,或 TSD)。



int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
int pthread_key_delete(pthread_key_t key);

void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *value);

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
pthread_once_t once_control = PTHREAD_ONCE_INIT;


threadattr.c
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>


#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>


#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        } while(0)


int main(void)
{
pthread_attr_t attr;
pthread_attr_init(&attr);

int state;
pthread_attr_getdetachstate(&attr, &state);
if (state == PTHREAD_CREATE_JOINABLE)
printf("detachstate:PTHREAD_CREATE_JOINABLE\n");
else if (state == PTHREAD_CREATE_DETACHED)
printf("detachstate:PTHREAD_CREATE_DETACHED");


size_t size;
pthread_attr_getstacksize(&attr, &size);
printf("stacksize:%d\n", size);


pthread_attr_getguardsize(&attr, &size);
printf("guardsize:%d\n", size);


int scope;
pthread_attr_getscope(&attr, &scope);
if (scope == PTHREAD_SCOPE_PROCESS)
printf("scope:PTHREAD_SCOPE_PROCESS\n");
if (scope == PTHREAD_SCOPE_SYSTEM)
printf("scope:PTHREAD_SCOPE_SYSTEM\n");



int policy;
pthread_attr_getschedpolicy(&attr, &policy);
if (policy == SCHED_FIFO)
printf("policy:SCHED_FIFO\n");
else if (policy == SCHED_RR)
printf("policy:SCHED_RR\n");
else if (policy == SCHED_OTHER)
printf("policy:SCHED_OTHER\n");



int inheritsched;
pthread_attr_getinheritsched(&attr, &inheritsched);
if (inheritsched == PTHREAD_INHERIT_SCHED)
printf("inheritsched:PTHREAD_INHERIT_SCHED\n");
else if (inheritsched == PTHREAD_EXPLICIT_SCHED)
                printf("inheritsched:PTHREAD_EXPLICIT_SCHED\n");


struct sched_param param;
pthread_attr_getschedparam(&attr, &param);
printf("sched_priority:%d\n", param.sched_priority);




pthread_attr_destroy(&attr);


int level;
level = pthread_getconcurrency();
printf("level:%d\n", level);
return 0;
}

tsd.c
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>


#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>


#define ERR_EXIT(m) \
        do \
        { \
                perror(m); \
                exit(EXIT_FAILURE); \
        } while(0)


typedef struct tsd
{
pthread_t tid;
char *str;
}tsd_t;


pthread_key_t key_tsd;
pthread_once_t once_control = PTHREAD_ONCE_INIT;


void destroy_routine(void *value)
{
printf("destory ...\n");
free(value);
}


void once_routine(void)
{
pthread_key_create(&key_tsd, destroy_routine);
printf("key init ...\n");
}


void* thread_routine(void *arg)
{
pthread_once(&once_control, once_routine);
tsd_t *value = http://www.mamicode.com/(tsd_t*)malloc(sizeof(tsd_t));
value->tid = pthread_self();
value->str = (char*)arg;


pthread_setspecific(key_tsd, value);
printf("%s setspecific %p\n", (char*)arg, value);
value = http://www.mamicode.com/pthread_getspecific(key_tsd);
printf("tid=0x%x str=%s\n", (int)value->tid, value->str);
sleep(2);
value = http://www.mamicode.com/pthread_getspecific(key_tsd);
        printf("tid=0x%x str=%s\n", (int)value->tid, value->str);
return NULL;
}


int main(void)
{
//pthread_key_create(&key_tsd, destroy_routine);

pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1, NULL, thread_routine, "thread1");
pthread_create(&tid2, NULL, thread_routine, "thread2");


pthread_join(tid1, NULL);
pthread_join(tid2, NULL);


pthread_key_delete(key_tsd);
return 0;
}

makefile:
.PHONY:clean all
CC=gcc
CFLAGS=-Wall -g
BIN=threadattr tsd
all:$(BIN)
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
threadattr:threadattr.o
$(CC) $(CFLAGS) $^ -o $@ -lpthread
tsd:tsd.o
$(CC) $(CFLAGS) $^ -o $@ -lpthread
clean:
rm -f *.o $(BIN)