一、多线程的创建和启动
一个多线程的程序是通过先创建后启用的方式运行起来的。可以在创建的时候传递参数,也可以在结束的时候返回参数。注意当第二个进程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