一.基本功能
1.最简单例子--创建线程
/*
*
* 创建线程
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
printf("this thread1!\n");
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,NULL);
sleep(4);
return 0;
}
2.传递简单参数
/*
*
* 线程传递参数
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("arg=%s\n",prm);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
sleep(4);
return 0;
}
3.传递结构体参数
/*
*
* 线程传递结构体
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct prm{
int in;
char ch[255];
int *p;
}oz;
void *thread1(void *arg)
{
oz *prm2 = NULL;
prm2=(oz*)arg;
printf(" prm:in=%d\n prm:ch=%s\n prm:p=%d\n",prm2->in,prm2->ch,*(prm2->p));
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
oz *prm1=malloc(sizeof(oz));
prm1->in=3;
sprintf(prm1->ch,"hello world!");
prm1->p=malloc(sizeof(prm1->p));
*(prm1->p)=123456;
ret = pthread_create(&tid,NULL,thread1,(void*)prm1);
sleep(4);
return 0;
}
4.主线程等待子线程结束
/*
*
* 主线程等待子线程结束
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("arg=%s\n",prm);
sleep(5);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
pthread_join(tid,NULL);
return 0;
}
5.获取线程id
/*
*
* 获取线程id
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("thread1's id=%lu\n",pthread_self());
sleep(5);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
printf("main thread's id=%lu\n",pthread_self());
printf("child thread's id=%lu\n",tid);
pthread_join(tid,NULL);
return 0;
}
6.子线程结束释放资源
/*
*
* 子线程结束释放资源
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
sleep(5);
pthread_detach(pthread_self());
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
pthread_join(tid,NULL);
return 0;
}
百度百科:pthread_detach
创建一个线程默认的状态是joinable, 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收(退出状态码),所以创建线程者应该 pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源(类似于wait,waitpid)但是调用pthread_join(pthread_id)后,如果该 线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此,比如在Web服务器中当 主线程为每个新来的链接创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的链接),这时可以在子线程中加入代码pthread_detach( pthread_self())或者父线程调用pthread_detach(thread_id)(非阻塞,可立即返回)这将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源。
7.创建多个子线程;子线程退出;发送退出信号给子线程
/*
*
* 创建多个子线程;子线程退出;发送退出信号给子线程
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread2(void *arg)
{
char *prm=NULL;
int i=5;
prm=(char*)arg;
while(1){
printf("thread2:%s\n",prm);
sleep(1);
}
}
void *thread1(void *arg)
{
char *prm=NULL;
int i=5;
prm=(char*)arg;
while(i--){
printf("thread1:%s\n",prm);
sleep(1);
}
pthread_exit("omg!"); pthread_detach(pthread_self());
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2;
void *join_ret;
ret = pthread_create(&tid1,NULL,thread1,(void*)argv[1]);
pthread_join(tid1,&join_ret);
printf("thread1 exit return:%s\n",(char *)join_ret);
ret = pthread_create(&tid2,NULL,thread2,(void*)argv[2]);
sleep(5);
if(!pthread_cancel(tid2))
printf("cancel pthread2\n");
pthread_join(tid2,NULL);
return 0;
}
8.一些错误的判断及处理
/*
*
* 错误的判断及处理
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
void *thread2(void *arg)
{
char *prm=NULL;
int i=5;
prm=(char*)arg;
while(1){
printf("thread2:%s\n",prm);
sleep(1);
}
}
void *thread1(void *arg)
{
char *prm=NULL;
int i=5;
prm=(char*)arg;
while(i--){
printf("thread1:%s\n",prm);
sleep(1);
}
if(pthread_detach(pthread_self())!=0)
exit(1);
pthread_exit("omg!");
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2;
void *join_ret;
ret = pthread_create(&tid1,NULL,thread1,(void*)argv[1]);
if(ret!=0){
printf("can't create thread1: %s\n", (char *)strerror(ret));
return -1;
}
if((ret=pthread_join(tid1,&join_ret))!=0){
printf("pthread_join error %s\n",(char *)strerror(ret));
return ret;
}
printf("thread1 exit return:%s\n",(char *)join_ret);
ret = pthread_create(&tid2,NULL,thread2,(void*)argv[2]);
if(ret!=0){
printf("can't create thread2: error num:%d\n", errno);
return errno;
}
sleep(5);
if(!pthread_cancel(tid2)){
printf("cancel pthread2\n");
}
else
pthread_join(tid2,NULL);
return 0;
}
9.主线程发送信号给子线程
/*
*
* 主线程发送信号给子线程
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
void kill_handler(int i)
{
printf("kill_handler\n");
}
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("arg=%s\n",prm);
while(1)
;
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
signal(SIGQUIT,kill_handler);
sleep(5);
if(pthread_kill(tid,SIGQUIT)==0)
printf("signal to pthread!\n");
while(1)
;
return 0;
}
10.pthread_cleanup_push/pop
/*
*
* pthread_cleanup_push/pop
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void cleanup(void *arg)
{
char* prm=NULL;
prm=(char*)arg;
printf("cleanup arg=%s\n",prm);
}
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
pthread_cleanup_push(cleanup,(void*)prm);
printf("arg=%s\n",prm);
pthread_cleanup_pop(1);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
pthread_join(tid,NULL);
return 0;
}
二.线程同步
第1部分 线程属性
1.detachstate
/*
*
* detachstate
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("arg=%s\n",prm);
sleep(5);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
pthread_attr_t attr;
int detachstate;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
ret = pthread_create(&tid,&attr,thread1,(void*)argv[1]);
if(ret!=0){
printf("pthread_create fail!\n");
return ret;
}
ret = pthread_attr_getdetachstate (&attr, &detachstate);
if(ret!=0){
printf("pthread_attr_getdetachstate error!\n");
}
if((detachstate==PTHREAD_CREATE_DETACHED)||(detachstate==PTHREAD_CREATE_JOINABLE)){
if(detachstate==PTHREAD_CREATE_DETACHED)
printf("PTHREAD_CREATE_DETACHED\n");
else
printf("PTHREAD_CREATE_JOINABLE\n");
}
pthread_attr_destroy(&attr);
pthread_join(tid,NULL);
return 0;
}
2.guardsize
/*
*
* guardsize
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
printf("arg=%s\n",prm);
sleep(5);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
pthread_attr_t attr;
size_t guardsize;
pthread_attr_init(&attr);
pthread_attr_setguardsize(&attr,4093);
ret = pthread_create(&tid,&attr,thread1,(void*)argv[1]);
if(ret!=0){
printf("pthread_create fail!\n");
return ret;
}
ret = pthread_attr_getguardsize (&attr, &guardsize);
if(ret!=0){
printf("pthread_attr_getguardsize error!\n");
}
else{
printf("guardsize=%d\n",guardsize);
}
pthread_attr_destroy(&attr);
pthread_join(tid,NULL);
return 0;
}
3.inheritsched
/*
*
* inheritsched
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
int ret;
pthread_attr_t attr;
int inheritsched;
pthread_attr_init(&attr);
pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
printf("arg=%s\n",prm);
sleep(5);
ret = pthread_attr_getinheritsched(&attr, &inheritsched);
if(ret!=0){
printf("pthread_attr_getguardsize error!\n");
}
if((inheritsched==PTHREAD_INHERIT_SCHED)||(inheritsched==PTHREAD_EXPLICIT_SCHED)){
if(inheritsched==PTHREAD_INHERIT_SCHED)
printf("PTHREAD_INHERIT_SCHED\n");
if(inheritsched==PTHREAD_EXPLICIT_SCHED)
printf("PTHREAD_EXPLICIT_SCHED\n");
}
pthread_attr_destroy(&attr);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid;
ret = pthread_create(&tid,NULL,thread1,(void*)argv[1]);
if(ret!=0){
printf("pthread_create fail!\n");
return ret;
}
pthread_join(tid,NULL);
return 0;
}
第2部分 mutex
1.mutex简单应用
//这个例子不好,可能无休止的运行,sum++的位置,及 sum 的判断条件,
使用trylock应该根据函数的返回值来决定是否进行sum的操作这才是正确的操作方式
/*
*
* mutex简单应用
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
int sum=0;
void *thread3(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
sleep(2);
pthread_mutex_trylock(&mutex);
while(1){
sum++;
if(sum==10)
break;
printf("thread3:%d\n",sum);
sleep(1);
}
pthread_mutex_unlock(&mutex);
}
void *thread2(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
sleep(1);
pthread_mutex_lock(&mutex);
while(1){
sum--;
if(sum<0)
break;
printf("thread2:%d\n",sum);
sleep(1);
}
pthread_mutex_unlock(&mutex);
}
void *thread1(void *arg)
{
char *prm=NULL;
prm=(char*)arg;
pthread_mutex_lock(&mutex);
while(1){
sum++;
if(sum==10)
break;
printf("thread1:%d\n",sum);
sleep(1);
}
pthread_mutex_unlock(&mutex);
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2,tid3;
pthread_mutex_init(&mutex,NULL);
ret = pthread_create(&tid1,NULL,thread1,(void*)argv[1]);
ret = pthread_create(&tid2,NULL,thread2,(void*)argv[1]);
ret = pthread_create(&tid3,NULL,thread2,(void*)argv[1]);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
pthread_mutex_trylock/lock区别
本质区别不就在“try”吗
选哪个取决于场景:
当前线程锁失败,也可以继续其它任务,用trylock合适
当前线程只有锁成功后,才会做一些有意义的工作,那就_lock,没必要轮询trylock
2.进程mutex
//此例程中共享内存使用有些问题,下面的程序若将“尝试注释”代码部分注释,加锁不能堵塞。重新使用一个新的pthread_mutex_t变量,则能正常使用
/*
*
* 进程mutex
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
typedef struct dev{
int i;
pthread_mutex_t mutex;
}DEV;
int main(int argc,char **argv)
{
int ret;
DEV *device=malloc(sizeof(DEV));
unsigned long j=0;
pthread_mutexattr_t mutexattr;
int shmid;
shmid=shmget(123,sizeof(DEV*),IPC_CREAT|0660);
shmctl(shmid,IPC_RMID,0);
shmid=shmget(123,sizeof(DEV*),IPC_CREAT|0660);
if(shmid==-1)
perror("shmget()");
device=(DEV*)shmat(shmid,0,0);pthread_mutexattr_init(&mutexattr); pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED); pthread_mutex_init(&(device->mutex),&mutexattr); ret = fork(); if(ret==-1){ printf("fork error!\n"); } if (ret==0){//将此句放到进城创建之前device=(DEV*)shmat(shmid,0,0);printf("father!\n"); char buffer[1024]; while(1){ pthread_mutex_lock(&(device->mutex)); (device->i)--; printf("father : i = %d\n",(device->i)); //pthread_mutex_unlock(&(device->mutex));//尝试注释 sleep(1); } pthread_mutexattr_destroy(&mutexattr); pthread_mutex_destroy(&(device->mutex)); return 0; } else{ printf("child!\n"); //放到进城创建之前device=(DEV*)shmat(shmid,0,0); while(1){ pthread_mutex_lock(&(device->mutex)); (device->i)++; printf("child : i = %d\n",(device->i)); pthread_mutex_unlock(&(device->mutex)); sleep(1); }
pthread_mutexattr_destroy(&mutexattr); pthread_mutex_destroy(&(device->mutex));return 0; }}
//修改之后的程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ipc.h>
typedef struct dev
{
int i;
pthread_mutex_t mutex;
}DEV;
int main(int argc,char *argv[])
{
int ret;
DEV *device = malloc(sizeof(DEV));
unsigned long j = 0;
pthread_mutexattr_t mutexattr;
pthread_mutex_t ev;
int shmid;
shmid = shmget(123,sizeof(DEV*),IPC_CREAT|0660);
shmctl(shmid,IPC_RMID,0);
shmid = shmget(123,sizeof(DEV*),IPC_CREAT|0660);
if(shmid == -1)
{
perror("shmget()");
}
device = (DEV*)shmat(shmid,NULL,0);
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&(device->mutex),&mutexattr);
pthread_mutex_init(&ev,NULL);
ret = fork();
if(ret == -1)
{
printf("fork error\n");
}
if(ret == 0)
{
//father
printf("father\n");
char buffer[1024];
while(1)
{
// pthread_mutex_lock(&ev);
// printf("lock ev\n");
pthread_mutex_lock(&(device->mutex));
printf(" father lock share mutex\n");
// (device->i)--;
(device->i)++;
printf("father: i = %d\n",device->i);
pthread_mutex_unlock(&(device->mutex));
sleep(1);
}
printf("father while out\n");
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&(device->mutex));
return 0;
}
else
{
sleep(5);
printf("child!\n");
device = (DEV*)shmat(shmid,0,0);
while(1)
{
pthread_mutex_lock(&(device->mutex));
(device->i)--;
printf("child: i = %d\n",device->i);
pthread_mutex_unlock(&(device->mutex));
sleep(1);
}
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&(device->mutex));
return 0;
}
}
3.线程mutex
/*
*
* 线程mutex
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int i=0;
char buffer[1024];
pthread_mutex_t mutex;
void *thread2(void *arg)
{
while(1){
pthread_mutex_lock(&mutex);
i++;
printf("thread2 %d\n",i);
if(fgets(buffer,1024,stdin)!=NULL)
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void *thread1(void *arg)
{
while(1){
pthread_mutex_lock(&mutex);
i--;
printf("thread1 %d\n",i);
if(fgets(buffer,1024,stdin)!=NULL)
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2;
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_PRIVATE);
pthread_mutex_init(&mutex,&mutexattr);
ret = pthread_create(&tid1,NULL,thread1,NULL);
ret = pthread_create(&tid1,NULL,thread2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
return 0;
}
自己的程序
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
int i=0;
char buffer[1024];
pthread_mutex_t mutex;
void *thread2(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
i++;
printf("thread2:%d\n",i);
if(fgets(buffer,1024,stdin)!=NULL)
{
pthread_mutex_unlock(&mutex);
printf("thread2 unlock\n");
}
sleep(1);
}
}
void *thread1(void * arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
i--;
printf("thread1:%d\n",i);
if(fgets(buffer,1024,stdin)!=NULL)
{
pthread_mutex_unlock(&mutex);
printf("thread1 unlock\n");
}
sleep(1);
}
}
int main(int argc,char *argv[])
{
int ret;
pthread_t tid1,tid2;
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_PRIVATE);
pthread_mutex_init(&mutex,&mutexattr);
ret = pthread_create(&tid1,NULL, thread1,NULL);
ret = pthread_create(&tid2,NULL, thread2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
return0;
}
第3部分 条件变量
1.线程+mutex+cond
/*
*
* 线程+mutex+cond
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int i=0;
void *thread2(void *arg)
{
while(i!=30){
pthread_mutex_lock(&mutex);
i++;
if(!(i%6))
pthread_cond_signal(&cond);
printf("thread2 %d\n",i);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
void *thread1(void *arg)
{
while(i!=30){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
printf("thread1-%d\n",i);
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2;
pthread_condattr_t attr;
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_PRIVATE);
pthread_condattr_init(&attr);
pthread_condattr_setpshared(&attr,PTHREAD_PROCESS_PRIVATE);
pthread_mutex_init(&mutex,&mutexattr);
pthread_cond_init(&cond,&attr);
ret = pthread_create(&tid1,NULL,thread1,(void*)argv[1]);
ret = pthread_create(&tid2,NULL,thread2,(void*)argv[1]);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("all thread done!\n");
pthread_condattr_destroy(&attr);
pthread_cond_destroy(&cond);
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
return 0;
}
线程+mutex+cond+互锁
//这个程序很烂,上锁和解锁不配对,逻辑混乱,非常容易造成死锁,全局变量i都没有设置,没有全局的结束变量。
关于cond参考之后的关于pthread_cond_wait和pthread_cond_signal博客文章,
/*
*
* 线程+mutex+cond+互锁
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int i=0;
char buffer[1024];
void *thread2(void *arg)
{
while(i!=30){
pthread_mutex_lock(&mutex);
if(fgets(buffer,1024,stdin)!=NULL){
if(buffer[0]!='2'){
pthread_cond_signal(&cond);
printf("thread2 pthread_cond_signal\n");
pthread_mutex_unlock(&mutex);
}
}
else{
printf("thread2 pthread_cond_wait\n");
pthread_cond_wait(&cond,&mutex);
}
printf("thread2 running\n");
sleep(1);
}
}
void *thread1(void *arg)
{
while(i!=30){
pthread_mutex_lock(&mutex);
if(fgets(buffer,1024,stdin)!=NULL){
if(buffer[0]!='1'){
pthread_cond_signal(&cond);
printf("thread1 pthread_cond_signal\n");
pthread_mutex_unlock(&mutex);
}
}
else{
printf("thread1 pthread_cond_wait\n");
pthread_cond_wait(&cond,&mutex);
}
printf("thread1 running\n");
sleep(1);
}
}
int main(int argc,char **argv)
{
int ret;
pthread_t tid1,tid2;
pthread_condattr_t attr;
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_PRIVATE);
pthread_condattr_init(&attr);
pthread_condattr_setpshared(&attr,PTHREAD_PROCESS_PRIVATE);
pthread_mutex_init(&mutex,&mutexattr);
pthread_cond_init(&cond,&attr);
ret = pthread_create(&tid1,NULL,thread1,(void*)argv[1]);
ret = pthread_create(&tid2,NULL,thread2,(void*)argv[1]);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("all thread done!\n");
pthread_condattr_destroy(&attr);
pthread_cond_destroy(&cond);
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
return 0;
}
1万+

被折叠的 条评论
为什么被折叠?



