一、多线程的创建和启动
一个多线程的程序是通过先创建后启用的方式运行起来的。可以在创建的时候传递参数,也可以在结束的时候返回参数。注意当第二个进程sleep时,第一个线程也在运行。当线程退出时,才继续向下运行主程序。上一个线程未退出,是不会向下执行主程序的。
- #include<stdio.h>
- #include<pthread.h>
- #include<stdlib.h>
- pthread_t tid,tid2;
- void* myfunc1(void* argv){
- printf("receive %s\n",(char*)argv);
- printf("New process: PID: %d,TID: %u.\n",getpid(),pthread_self()); //得到TID
- printf("New process: PID: %d,TID: %u.\n",getpid(),tid);
- //sleep(6); //测试结果为6秒以后阻塞的信息一起输出
- sleep(2);
- pthread_exit((void*)1);
- }
- void* myfunc2(void* argv){
- printf("the second thread is running......\n");
- sleep(3);
- return (void*)2;
- }
- int main(){
- void* ret;
- if(pthread_create(&tid,NULL,myfunc1,"gaga")!=0){ //传递参数
- printf("create error\n");
- exit(1);
- }
- if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- printf("the pthread id is %d \n",tid);
- printf("Main process: PID: %d,TID: %u.\n",getpid(),pthread_self());
- if(pthread_join(tid,&ret) !=0){
- printf("join thread 1 error!\n");
- return 1;
- }
- printf("wa kakaka it is %d\n",(int)ret);
- if(pthread_join(tid2,&ret) != 0){
- printf("join thread 2 error!\n");
- return 1;
- }
- printf(" %d \n",(int)ret);
- }
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
pthread_t tid,tid2;
void* myfunc1(void* argv){
printf("receive %s\n",(char*)argv);
printf("New process: PID: %d,TID: %u.\n",getpid(),pthread_self()); //得到TID
printf("New process: PID: %d,TID: %u.\n",getpid(),tid);
//sleep(6); //测试结果为6秒以后阻塞的信息一起输出
sleep(2);
pthread_exit((void*)1);
}
void* myfunc2(void* argv){
printf("the second thread is running......\n");
sleep(3);
return (void*)2;
}
int main(){
void* ret;
if(pthread_create(&tid,NULL,myfunc1,"gaga")!=0){ //传递参数
printf("create error\n");
exit(1);
}
if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
printf("create error\n");
exit(1);
}
printf("the pthread id is %d \n",tid);
printf("Main process: PID: %d,TID: %u.\n",getpid(),pthread_self());
if(pthread_join(tid,&ret) !=0){
printf("join thread 1 error!\n");
return 1;
}
printf("wa kakaka it is %d\n",(int)ret);
if(pthread_join(tid2,&ret) != 0){
printf("join thread 2 error!\n");
return 1;
}
printf(" %d \n",(int)ret);
}
运行结果为:
- [fsy@localhost thread]$ ./thread_create
- the pthread id is -1216914576 //此处还未初始化
- Main process: PID: 6333,TID: 3078055616.
- the second thread is running...... //2线程先运行然后sleep
- receive gaga //1线程运行
- New process: PID: 6333,TID: 3078052720.
- New process: PID: 6333,TID: 3078052720.
- wa kakaka it is 1 //两秒后打印,sleep(6)就在此阻塞6秒
- 2 //2线程退出,再运行主程序
- [fsy@localhost thread]$
[fsy@localhost thread]$ ./thread_create
the pthread id is -1216914576 //此处还未初始化
Main process: PID: 6333,TID: 3078055616.
the second thread is running...... //2线程先运行然后sleep
receive gaga //1线程运行
New process: PID: 6333,TID: 3078052720.
New process: PID: 6333,TID: 3078052720.
wa kakaka it is 1 //两秒后打印,sleep(6)就在此阻塞6秒
2 //2线程退出,再运行主程序
[fsy@localhost thread]$
二、取消线程
通过pthread_cancel() 函数来结束另一个线程。
- #include<stdio.h>
- #include<pthread.h>
- #include<stdlib.h>
- pthread_t tid,tid2;
- void* myfunc1(void* argv){
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); //设置可被其他进程取消
- while(1){
- printf("thread 1 is read to be killed\n");
- sleep(1);
- }
- return 0;
- }
- void* myfunc2(void* argv){
- printf("thread 2 is running!\n");
- sleep(3);
- if(pthread_cancel(tid) == 0){
- printf("Thread 2 will kill Thread 1\n");
- }
- return 0;
- }
- int main(){
- if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- if(pthread_join(tid,NULL) !=0){
- printf("join thread 1 error!\n");
- return 1;
- }
- printf("Thread 1 is never back.....\n");
- if(pthread_join(tid2,NULL) != 0){
- printf("join thread 2 error!\n");
- return 1;
- }
- }
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
pthread_t tid,tid2;
void* myfunc1(void* argv){
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); //设置可被其他进程取消
while(1){
printf("thread 1 is read to be killed\n");
sleep(1);
}
return 0;
}
void* myfunc2(void* argv){
printf("thread 2 is running!\n");
sleep(3);
if(pthread_cancel(tid) == 0){
printf("Thread 2 will kill Thread 1\n");
}
return 0;
}
int main(){
if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
printf("create error\n");
exit(1);
}
if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
printf("create error\n");
exit(1);
}
if(pthread_join(tid,NULL) !=0){
printf("join thread 1 error!\n");
return 1;
}
printf("Thread 1 is never back.....\n");
if(pthread_join(tid2,NULL) != 0){
printf("join thread 2 error!\n");
return 1;
}
}
运行输出结果为:
- [fsy@localhost thread]$ ./thread
- thread 2 is running!
- thread 1 is read to be killed
- thread 1 is read to be killed
- thread 1 is read to be killed
- Thread 2 will kill Thread 1
- Thread 1 is never back.....
[fsy@localhost thread]$ ./thread
thread 2 is running!
thread 1 is read to be killed
thread 1 is read to be killed
thread 1 is read to be killed
Thread 2 will kill Thread 1
Thread 1 is never back.....
三、互斥锁
两个进程同时访问一个数据就需要加锁。
用pthread_mutex_lock、pthread_mutex_unlock控制锁。pthread_mutex_destory删除锁。pthread_mutex_trylock判断是否加锁。
- #include<stdio.h>
- #include<pthread.h>
- #include<stdlib.h>
- pthread_mutex_t mutex;
- pthread_t tid,tid2;
- int meter=0;
- int seconds=0;
- void* myfunc1(void* argv){
- pthread_mutex_lock(&mutex); //上锁
- while(1){
- printf("thread is running %d seconds it is %d meter\n",seconds,meter);
- meter++;
- seconds++;
- sleep(1);
- }
- pthread_mutex_unlock(&mutex); //去锁
- return 0;
- }
- void* myfunc2(void* argv){
- sleep(1);
- pthread_mutex_lock(&mutex);
- while(1){
- meter++;
- seconds++;
- }
- pthread_mutex_unlock(&mutex);
- }
- int main(){
- pthread_mutex_init(&mutex,NULL); //第二个参数NULL为互斥锁
- if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- if(pthread_join(tid,NULL) !=0){
- printf("join thread 1 error!\n");
- return 1;
- }
- if(pthread_join(tid2,NULL) != 0){
- printf("join thread 2 error!\n");
- return 1;
- }
- }
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
pthread_mutex_t mutex;
pthread_t tid,tid2;
int meter=0;
int seconds=0;
void* myfunc1(void* argv){
pthread_mutex_lock(&mutex); //上锁
while(1){
printf("thread is running %d seconds it is %d meter\n",seconds,meter);
meter++;
seconds++;
sleep(1);
}
pthread_mutex_unlock(&mutex); //去锁
return 0;
}
void* myfunc2(void* argv){
sleep(1);
pthread_mutex_lock(&mutex);
while(1){
meter++;
seconds++;
}
pthread_mutex_unlock(&mutex);
}
int main(){
pthread_mutex_init(&mutex,NULL); //第二个参数NULL为互斥锁
if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
printf("create error\n");
exit(1);
}
if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
printf("create error\n");
exit(1);
}
if(pthread_join(tid,NULL) !=0){
printf("join thread 1 error!\n");
return 1;
}
if(pthread_join(tid2,NULL) != 0){
printf("join thread 2 error!\n");
return 1;
}
}
经过加锁,能够依次输出数字。
四、信号量
解决同步问题,加锁可以用信号量,它更强大一些,可以用它来控制进程的运行顺序。
sem_init()初始化一个函数。sem_wait()执行P操作。sem_post()执行V操作。sem_destory()销毁信号量。
- #include<stdio.h>
- #include<pthread.h>
- #include<stdlib.h>
- #include<semaphore.h>
- pthread_t tid,tid2;
- sem_t sem1;
- sem_t sem2;
- void* myfunc1(void* argv){
- sem_wait(&sem1); //p操作使其他线程无法访问
- sleep(2);
- printf("thread 1 is running....\n");
- sem_post(&sem2); //V操作使2线程可以运行
- }
- void* myfunc2(void* argv){
- sem_wait(&sem2); //在未进行V操作之前会卡住
- printf("thread 2 is running!\n");
- sleep(1);
- sem_post(&sem1);
- }
- int main(){
- if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
- printf("create error\n");
- exit(1);
- }
- //第二个参数为固定的0,第三个参数为1表示线程可访问,0表示线程不可访问
- sem_init(&sem1,0,1);
- sem_init(&sem2,0,0);
- if(pthread_join(tid,NULL) !=0){
- printf("join thread 1 error!\n");
- return 1;
- }
- if(pthread_join(tid2,NULL) != 0){
- printf("join thread 2 error!\n");
- return 1;
- }
- sem_destroy(&sem1);
- sem_destroy(&sem2);
- printf("finish!\n");
- }
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<semaphore.h>
pthread_t tid,tid2;
sem_t sem1;
sem_t sem2;
void* myfunc1(void* argv){
sem_wait(&sem1); //p操作使其他线程无法访问
sleep(2);
printf("thread 1 is running....\n");
sem_post(&sem2); //V操作使2线程可以运行
}
void* myfunc2(void* argv){
sem_wait(&sem2); //在未进行V操作之前会卡住
printf("thread 2 is running!\n");
sleep(1);
sem_post(&sem1);
}
int main(){
if(pthread_create(&tid,NULL,myfunc1,NULL)!=0){
printf("create error\n");
exit(1);
}
if(pthread_create(&tid2,NULL,myfunc2,NULL)!=0){
printf("create error\n");
exit(1);
}
//第二个参数为固定的0,第三个参数为1表示线程可访问,0表示线程不可访问
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
if(pthread_join(tid,NULL) !=0){
printf("join thread 1 error!\n");
return 1;
}
if(pthread_join(tid2,NULL) != 0){
printf("join thread 2 error!\n");
return 1;
}
sem_destroy(&sem1);
sem_destroy(&sem2);
printf("finish!\n");
}
通过信号量和P、V的操作实现了线程同步的控制。
本篇博客出自 阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/6882586