Linux 多线程程序设计-LS13

1.linux进程与线程
进程是程序执行时的一个实例,即它是程序已经执行到何种程度的数据结构的汇集。从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。Linux通过fork创建出该进程的一份拷贝,这个新进程拥有自己的变量和自己的PID,它的时间调度是独立的,它的执行几乎完全独立于父进程。
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),Linux进程创建一个新线程时,线程将拥有自己的栈(因为线程有自己的局部变量),但与它的创建者共享全局变量、文件描述符、信号句柄和当前目录状态,线程与同属一个进程的其他的线程共享进程所拥有的全部资源。。
进程可以看成一个资源的基本单位,而线程是程序调度的基本单位,一个进程内部的线程之间共享进程获得的时间片:进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。
关于进程与线程更详尽的说明可以参考网页:
1)https://www.cnblogs.com/skynet/archive/2010/10/30/1865267.html

2.Linux下的线程操作函数
线程函数:创建线程、取消线程、退出线程、等待线程、查询线程ID…
1)int pthread_create(pthread_t tid, const pthread_attr_t *attr, void (func) (void ), void *arg);
2)int pthread_cancel(pthread_t thread);
3)int pthread_join (pthread_t tid, void **status);
4)pthread_t pthread_self (void);
5)int pthread_detach (pthread_t tid);
6)void pthread_exit (void *status);
线程间通信函数:
1)线程同步
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
2)线程互斥
int pthread_mutex_lock(pthread_mutex_t * mptr);
int pthread_mutex_unlock(pthread_mutex_t * mptr);

熟悉这些函数,是完成多线程程序设计的必要条件,也是时程序更为健壮的前提,下面分别对这些函数进行说明,你也可以通过linux系统的man命令查看各函数的说明。

3.关键函数说明
1)创建线程:pthread_create

函数名 pthread_create
函数原形 int pthread_create(pthread_t tid, const pthread_attr_t *attr, void (func) (void ), void *arg);
函数功能 创建一个线程
所属头文件 #include

#include <pthread.h>

返回值 0:成功; 大于零的正数:失败
参数说明 pthread_t tid:指定要等待的线程ID
void ** status:如果不为NULL,那么线程的返回值存储在status指向的空间中(这就是为什么status是二级指针的原因!这种参数也称为“值-结果”参数)。

4)线程ID查询:pthread_self
函数名 pthread_self
函数原形 pthread_t pthread_self (void);

函数功能 用于返回当前线程的ID
所属头文件
返回值 线程ID:成功
参数说明

5)
函数名 pthread_detach
函数原形 int pthread_detach (pthread_t tid);

函数功能 用于是指定线程变为分离状态,就像进程脱离终端而变为后台进程类似
所属头文件

#include <pthread.h>

返回值 0:成功; 大于零的正数:失败
参数说明

6)线程终止:pthread_exit
函数名 pthread_exit
函数原形 void pthread_exit (void *status);
函数功能 pthread_exit用于终止线程,可以指定返回值,以便其他线程通过pthread_join函数获取该线程的返回值。
所属头文件

#include <pthread.h>

返回值 无
参数说明 void *status:指针线程终止的返回值。线程通过调用pthread_exit函数终止执行,并返回一个指向某对象的指针。注意:绝不能用它返回一个指向局部变量的指针,因为线程调用该函数后,这个局部变量就不存在了,这将引起严重的程序漏洞。

7)线程互斥之互斥锁(加锁):pthread_mutex_lock
项目 备注内容
函数名 pthread_mutex_lock
函数原形 int pthread_mutex_lock(pthread_mutex_t * mptr);
函数功能 在对临界资源进行操作之前需要pthread_mutex_lock先加锁,操作完之后pthread_mutex_unlock再解锁。
所属头文件

#include <pthread.h>

返回值 0:成功; 大于零的正数:失败
参数说明 而且在这之前需要声明一个pthread_mutex_t类型的变量,用作前面两个函数的参数

8)线程互斥之互斥锁(解锁):pthread_mutex_unlock
函数名 pthread_mutex_unlock
函数原形 int pthread_mutex_unlock(pthread_mutex_t * mptr);
函数功能 在对临界资源进行操作之前需要pthread_mutex_lock先加锁,操作完之后pthread_mutex_unlock再解锁。
所属头文件 #include

#include <pthread.h>

返回值 0:成功; 大于零的正数:失败
参数说明 在调用者两个函数之前需要声明一个pthread_cond_t类型的变量,用于这两个函数的参数。

10)线程同步之信号量传输:pthread_cond_signal
函数名 pthread_cond_signal
函数原形 int pthread_cond_signal(pthread_cond_t *cptr);
函数功能 用于通知阻塞的线程某个特定的条件为真了
所属头文件

#include <pthread.h>

返回值 0:成功; 大于零的正数:失败
参数说明 在调用者两个函数之前需要声明一个pthread_cond_t类型的变量,用于这两个函数的参数。

程序设计:
编写UDP网络客户端多线程程序,在主函数中建立两个线程,分别完成UDP网络数据的发送、接收。
编写UDP网络服务器多线程程序,在主函数中建立两个线程,分别完成UDP网络数据的发送、接收。实验测试:客户端与服务器的发送接收都可同时进行,实现全双工。测试现象如图所示:
这里写图片描述

遇到的问题与解决方式(客户端与服务器在程序设计的区别):客户端需要提前知道服务器的ID,而服务器是在通过跟客户端通信后再获取到客户端的ID,因此在服务器程序设计时需要在接收到客户端的ID后进行保存,并在发送线程中使用,从而需要在接收线程与接收线程中进行信息传递(本方案在服务器程序设计时是通过设置全局变量的方式得到客户端ID的)

多线程下的udp客户端与服务器的具体代码请查看链接下载:
http://download.csdn.net/download/zxp121127/10114245

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
/************************************************ * * The classic producer-consumer example. * Illustrates mutexes and conditions. * by Zou jian guo * 2003-12-22 * *************************************************/ #include #include #include #include "pthread.h" #define BUFFER_SIZE 16 /* Circular buffer of integers. */ struct prodcons { int buffer[BUFFER_SIZE]; /* the actual data */ pthread_mutex_t lock; /* mutex ensuring exclusive access to buffer */ int readpos, writepos; /* positions for reading and writing */ pthread_cond_t notempty; /* signaled when buffer is not empty */ pthread_cond_t notfull; /* signaled when buffer is not full */ }; /*--------------------------------------------------------*/ /* Initialize a buffer */ void init(struct prodcons * b) { pthread_mutex_init(&b->lock, NULL); pthread_cond_init(&b->notempty, NULL); pthread_cond_init(&b->notfull, NULL); b->readpos = 0; b->writepos = 0; } /*--------------------------------------------------------*/ /* Store an integer in the buffer */ void put(struct prodcons * b, int data) { pthread_mutex_lock(&b->lock); /* Wait until buffer is not full */ while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) { printf("wait for not full\n"); pthread_cond_wait(&b->notfull, &b->lock); } /* Write the data and advance write pointer */ b->buffer[b->writepos] = data; b->writepos++; if (b->writepos >= BUFFER_SIZE) b->writepos = 0; /* Signal that the buffer is now not empty */ pthread_cond_signal(&b->notempty); pthread_mutex_unlock(&b->lock); } /*--------------------------------------------------------*/ /* Read and remove an integer from the buffer */ int get(struct prodcons * b) { int data; pthread_mutex_lock(&b->lock); /* Wait until buffer is not empty */ while (b->writepos == b->readpos) { printf("wait for not empty\n"); pthread_cond_wait(&b->notempty, &b->

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值