线程属性
初始化与销毁属性
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, ¶m);
printf("sched_priority:%d\n", param.sched_priority);
pthread_attr_destroy(&attr);
int level;
level = pthread_getconcurrency();
printf("level:%d\n", level);
return 0;
}
#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, ¶m);
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 = (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 = pthread_getspecific(key_tsd);
printf("tid=0x%x str=%s\n", (int)value->tid, value->str);
sleep(2);
value = 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;
}
#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 = (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 = pthread_getspecific(key_tsd);
printf("tid=0x%x str=%s\n", (int)value->tid, value->str);
sleep(2);
value = 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)
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)