lunux多线程编程

1.进程与线程

  1)用户空间角度:

  进程:fork()创建进程,在创建时,重新申请了内存空间,copy了父进程的所有信息。

  线程:pthread_create()创建进程时,只申请自己的栈空间。

  2)内核空间:

  对内核空间,两者都有自己的pid,因此内核空间不区分。

2.基本函数:

  1)创建线程:

  #include <pthread.h>

  extern in t pthread_create(pthread_t *tidp,const pthread_attr_t *attr,(void*)(*start_rtn)(void*),void  *arg

  第1个参数: 线程id

  第2个参数:用来设置线程属性,通常为NULL

  第3个参数:需要创建线程的执行代码地址

  第4个参数:线程执行参数

  pthread.h支持的是POSIX,编译时加-lpthread

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/syscall.h>
struct data{
        int i;
        int j;
};
void *hello(struct data *str)
{
        printf("child,  the tid=%lu, pid=%ld\n",pthread_self(),syscall(SYS_gettid));
        printf("arg.i=%d\narg.j=%d \n",str->i,str->j);
        sleep(1);
}

int main(int agrc,char *agrv[])
{
        struct data test;
        pthread_t thread_id;
        test.i=20;
        test.j=50;
        pthread_create(&thread_id,NULL,(void*)*hello,&test);
        printf("parent, the tid=%lu,pid=%ld\n",pthread_self(),syscall(SYS_gettid));
        pthread_join(thread_id,NULL);
}

  2)线程退出:

  extern void pthread_exit(void *_retval),参数为线程取消状态。

  int pthread _cancel(pthread_t thread)

  线程取消的清理:

  int pthread_cleanup_push(void (*routine)(void*),void *arg)

  int pthread_cleanup_pop(int execute)

 1 #include<pthread.h>
 2 #include<unistd.h>
 3 #include<stdlib.h>
 4 #include<stdio.h>
 5 
 6 void cleanup()
 7 {
 8         printf("cleanup\n");
 9 }
10 void *test_cancel(void)
11 {
12         pthread_cleanup_push(cleanup,NULL);
13         printf("test_cancel\n");
14         while(1)
15         {
16                 printf("test message\n");
17                 sleep(1);
18         }
19         pthread_cleanup_pop(1);
20 }
21 int main()
22 {
23         pthread_t tid;
24         pthread_create(&tid,NULL,(void *)test_cancel,NULL);
25         sleep(2);
26         pthread_cancel(tid);
27         pthread_join(tid,NULL);   // pthread_join()等待线程执行
28 }

  3)线程与私有数据:

  int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))   //创建私有数据

  int pthread_key_delete(pthread_key_t key)  //删除私有数据

  int pthread_setspecific(pthread_key_t key,const void *pointer)  //读,pointer是与key相关联的

  int pthread_getspecific(pthread_key_t key)  //写

3.互斥锁:以排他的方式防止共享数据并发的访问

  1)初始化:

  #include <pthread.h>

  int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr)

  第1个参数:所要指向的互斥锁指针

  第2个参数:指向属性对象的指针,如NULL使用默认属性

  2)申请互斥锁:

  int pthread_mutex_lock(pthread_mutex_t  *mutex)       //阻塞方式申请

  int pthread_mutex_trylock(pthread_mutex_t  *mutex)  //非阻塞方式申请

  3)释放互斥锁:

  int pthread_mutex_unlock(pthread_mutex_t  *mutex)

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <stdlib.h>
 4 #include <pthread.h>
 5 #include <semaphore.h>
 6 #include <string.h>
 7 
 8 void *thread_function(void *arg);
 9 
10 pthread_mutex_t work_mutex;
11 
12 #define WORK_SIZE 1024
13 char work_area[WORK_SIZE];
14 int time_to_exit = 0;
15 
16 int main(int argc,char *argv[])
17 {
18     int res;
19     pthread_t a_thread;
20     void *thread_result;
21     res = pthread_mutex_init(&work_mutex, NULL); //init mutex 
22     if (res != 0)
23         {
24         perror("Mutex initialization failed");
25         exit(EXIT_FAILURE);
26     }
27     res = pthread_create(&a_thread, NULL, thread_function, NULL);//create new thread
28     if (res != 0)
29         {
30         perror("Thread creation failed");
31         exit(EXIT_FAILURE);
32     }
33     pthread_mutex_lock(&work_mutex);                    //lock the mutex
34     printf("Input some text. Enter ‘end‘ to finish\n");
35     while(!time_to_exit)
36         {
37         fgets(work_area, WORK_SIZE, stdin);             //get a string from stdin
38         pthread_mutex_unlock(&work_mutex);              //unlock the mutex
39         while(1)
40                 {
41             pthread_mutex_lock(&work_mutex);    //lock the mutex
42             if (work_area[0] != \0)
43                         {
44                 pthread_mutex_unlock(&work_mutex);      //unlock the mutex
45                 sleep(1);
46             }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。