学习Pthread时的笔记和demo,感谢各路大神的分享
pthread_create
#include
#include
void * thread(void *arg)
{
printf("arg is %d.\n", *(int *)arg);
*(int *)arg = 123456;
return arg;
}
int main(int argc, char const *argv[])
{
pthread_t tid;
int arg = 111111;
int res = pthread_create(&tid, NULL, thread, &arg);
if (res != 0)
{
perror("pthread_create");
return -1;
}
printf("main thread.\n");
int *thread_res = NULL;
res = pthread_join(tid, (void **)&thread_res);
if (res != 0 || !thread_res)
{
perror("pthread_join");
return -1;
}
printf("thread return val = %d\n", *thread_res);
return 0;
}
复制代码
join detach
线程的合并是一种主动回收线程资源的方案。当一个进程或线程调用了针对其它线程的pthread_join()接口,就是线程合并了。这个接口会阻塞调用进程或线程,直到被合并的线程结束为止。当被合并线程结束,pthread_join()接口就会回收这个线程的资源,并将这个线程的返回值返回给合并者。
与线程合并相对应的另外一种线程资源回收机制是线程分离,调用接口是pthread_detach()。线程分离是将线程资源的回收工作交由系统自动来完成,也就是说当被分离的线程结束之后,系统会自动回收它的资源。因为线程分离是启动系统的自动回收机制,那么程序也就无法获得被分离线程的返回值,这就使得pthread_detach()接口只要拥有一个参数就行了,那就是被分离线程句柄。
调用pthread_create()函数,线程要么是合并的(默认)要么是分离的。如果是合并属性的线程,那么必须使用pthread_join()等待结束,否则所占用的资源不会得到释放从而造成资源泄露。而分离属性的线程在结束的时候会自动释放所占用的资源。
一个合并属性线程只能用一个pthread_join()函数来等待结束。如果有多个pthread_join函数则只有第一个执行到的有效,其他的都会直接返回错误。
detach demo
#include
#include
void * func(void *a)
{
printf("other thread\n");
return a;
}
int main(int argc, char *argv[])
{
pthread_attr_t attr;
pthread_attr_init(&attr);
//PTHREAD_CREATE_DETACHED(分离的)PTHREAD_CREATE_JOINABLE(可合并的,也是默认属性)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_t th;
pthread_create(&th, &attr, func, NULL);
printf("main thread\n");
pthread_attr_destroy(&attr);
return 0;
}
复制代码
join demo
#include
#include
#include
void * func(void *arg)
{
int tid = (int)pthread_self();
printf("tid %d start\n",tid);
double result = 0.0;
for (int i = 0;i < 100000;++i)
{
result += (double)random();
}
printf("tid %d result = %e\n",tid,result);
printf("tid %d end\n",tid);
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_t thread[5];
int len = sizeof(thread)/sizeof(pthread_t);
for (int i = 0;i < len;++i)
{
int res = pthread_create(&thread[i], &attr, func, NULL);
if (res != 0)
{
perror("pthread_create : ");
exit(-1);
}
}
pthread_attr_destroy(&attr);
for (int i = 0;i < len;++i)
{
void *tres = NULL;
int res = pthread_join(thread[i], &tres);
if (res != 0)
{
perror("pthread_join : ");
exit(-1);
}
printf("thread %d joined\n",i);
}
return 0;
}
复制代码
contention scope
#include
#include
void * start(void *a)
{
return a;
}
int main(int argc, char const *argv[])
{
pthread_attr_t attr;
pthread_t th;
pthread_attr_init(&attr);
/*
scope属性表示线程间竞争CPU的范围,也就是说线程优先级的有效范围。POSIX的标准中定义了两个值:PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争CPU时间,后者表示仅与同进程中的线程竞争CPU。
*/
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&th, &attr, start, NULL);
pthread_attr_destroy(&attr);
return 0;
}
复制代码
lock
mutex lock
#include
#include
#include
#include
#include
pthread_mutex_t mutex;
int sharedVar = 0;
void * func1(void *arg)
{
time_t end = time(NULL) + 10;
while(time(NULL) < end)
{
int ret = pthread_mutex_trylock(&mutex);
if(ret == EBUSY)
{
printf("already lock\n");
}
else if (ret == EINVAL)
{
printf("lock is not init\n");
}
else if (ret == 0)
{
printf("thread 1 locked\n");
++sharedVar;
pthread_mutex_unlock(&mutex);
}
sleep(1);
}
return NULL;
}
void * func2(void *arg)
{
time_t end = time(NULL) + 10;
while (time(NULL) < end)
{
pthread_mutex_lock(&mutex);
printf("thread 2 locked\n");
++sharedVar;
sleep(1);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mutex, NULL);
pthread_t th1;
pthread_create(&th1, NULL, func1, NULL);
pthread_t th2;
pthread_create(&th2, NULL, func2, NULL);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_mutex_destroy(&mutex);
printf("shared var = %d\n", sharedVar);
return 0;
}
复制代码
condition lock
#include
#include
#include
pthread_mutex_t mutex;
pthread_cond_t cond;
typedef struct
{
char buff[5];
int count;
} buffer;
buffer sharedData = {.buff = "", .count = 0};
char ch = 'A';
void * producer(void *arg)
{
printf("producer start\n");
while (ch != 'Z')
{
pthread_mutex_lock(&mutex);
if (sharedData.count < 5)
{
sharedData.buff[sharedData.count] = ch;
printf("producer get char %c\n", ch);
ch++;
sharedData.count++;
if (sharedData.count == 5)
{
printf("producer signal\n");
pthread_cond_signal(&cond);
}
}
pthread_mutex_unlock(&mutex);
}
printf("producer end\n");
return NULL;
}
void * consumer(void *arg)
{
printf("consumer start\n");
while (ch != 'Z')
{
pthread_mutex_lock(&mutex);
printf("consumer wait\n");
pthread_cond_wait(&cond, &mutex);
printf("consumer write\n");
for (int i = 0; sharedData.buff[i] && sharedData.count; ++i)
{
printf("%c",sharedData.buff[i]);
--sharedData.count;
}
printf("\n");
pthread_mutex_unlock(&mutex);
}
printf("consumer end\n");
return NULL;
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_t cth;
pthread_create(&cth, NULL, consumer, NULL);
pthread_t pth;
pthread_create(&pth, NULL, producer, NULL);
pthread_join(cth, NULL);
pthread_join(pth, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
复制代码
thread storage
#include
#include
#include
pthread_key_t key;
typedef struct
{
int data;
} ThreadData;
void * func(void *arg)
{
ThreadData *data = (ThreadData *)arg;
printf("thread %d start\n", data->data);
pthread_setspecific(key,data);
printf("thread data is %d\n", ((ThreadData *)pthread_getspecific(key))->data);
printf("thread %d exit\n", data->data);
return arg;
}
void deconstruct(void *arg)
{
printf("thread %d data free\n", ((ThreadData *)arg)->data);
free(arg);
}
int main(int argc, char *argv[])
{
pthread_t thread[5];
size_t len = sizeof(thread)/sizeof(pthread_t);
pthread_key_create(&key,deconstruct);
for (int i = 0; i < len; ++i)
{
ThreadData *threadData = (ThreadData *)malloc(sizeof(ThreadData));
threadData->data = i;
pthread_create(&thread[i], NULL, func, threadData);
}
for (int i = 0; i < len; ++i)
{
pthread_join(thread[i], NULL);
}
pthread_key_delete(key);
return 0;
}
复制代码