Linux练习_线程练习
Posted Leslie X徐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux练习_线程练习相关的知识,希望对你有一定的参考价值。
线程练习
题1
要求:
- 创建3个子线程a,b,c,再创建一个线程回收线程z
- 在z线程内循环调用join来回收a,b,c线程
- 并且将abc线程返回值打包成数组在main主函数中输出
- 使用分离式的专用线程来回收线程
/*
* 线程资源回收线程.c
* 创建3个子线程a,b,c,再创建一个线程回收线程z
* 在z线程内循环调用join来回收a,b,c线程
* 并且将abc线程返回值打包成数组在main主函数中输出
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int i,result[3];
pthread_t a,b,c,z;
void* th_fn(void* arg)
{
printf("pthread start!\\n");
pthread_exit((void*)i++);
}
void* clean(void* arg)
{
printf("clean start!\\n");
pthread_join(a,(void*)&result[2]);
pthread_join(b,(void*)&result[1]);
pthread_join(c,(void*)&result[0]);
return NULL;
}
int main(int argc, char **argv)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&a,NULL,th_fn,NULL);
pthread_create(&b,NULL,th_fn,NULL);
pthread_create(&c,NULL,th_fn,NULL);
pthread_create(&z,&attr,clean,NULL);
sleep(1); //主线程需要休眠1s来让线程执行完毕
pthread_attr_destroy(&attr);
int j=3;
while(j--)printf("%d\\n",result[j]);
return 0;
}
输出:
pthread start!
pthread start!
clean start!
pthread start!
0
1
2
- 使用清理函数编写(cleanup_pop&push)
/*
* 线程资源回收线程.c
* 创建3个子线程a,b,c,再创建一个线程清理函数
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int i,result[3];
pthread_t a,b,c;
void* th_fn(void* arg)
{
printf("pthread start!\\n");
return (void*)i++;
}
void clean(void* arg)
{
printf("clean start!\\n");
pthread_join(a,(void*)&result[2]);
pthread_join(b,(void*)&result[1]);
pthread_join(c,(void*)&result[0]);
return;
}
int main(int argc, char **argv)
{
//添加清理函数
pthread_cleanup_push(clean,0);
pthread_create(&a,0,th_fn,0);
pthread_create(&b,0,th_fn,0);
pthread_create(&c,0,th_fn,0);
//清理函数使用
pthread_cleanup_pop(1);
int j=3;
while(j--)printf("%d\\n",result[j]);
return 0;
}
- 使用cancel:cancel无法获取返回值,也无法清理资源
/*
* 线程资源回收线程.c
* 创建3个子线程a,b,c,再创建一个线程回收函数
使用pthread_cancel回收线程
*/
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int i,result[3];
pthread_t a,b,c;
void* th_fn(void* arg)
{
printf("pthread start!\\n");
result[i]=i;
++i;
pthread_exit(NULL);
}
void clean(void* arg)
{
printf("clean start!\\n");
pthread_cancel(a);
pthread_cancel(b);
pthread_cancel(c);
return;
}
int main(int argc, char **argv)
{
//添加清理函数
pthread_cleanup_push(clean,0);
pthread_create(&a,0,th_fn,0);
pthread_create(&b,0,th_fn,0);
pthread_create(&c,0,th_fn,0);
//注意需要将线程设置为分离式
pthread_detach(a);
pthread_detach(b);
pthread_detach(c);
//清理函数使用
pthread_cleanup_pop(1);
int j=3;
while(j--)printf("%d\\n",result[j]);
return 0;
}
输出:
pthread start!
pthread start!
clean start!
pthread start!
2
1
0
题2
cancel的使用:
/*
* pthread_cancel的使用.c
*
*/
#include <stdio.h>
#include <pthread.h>
void* th_fn(void* arg)
{
//pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,0);
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
printf("1\\n");
printf("2\\n");
pthread_cancel(pthread_self());
printf("3\\n");
pthread_testcancel();
printf("4\\n");
return (void*)0;
}
int main(int argc, char **argv)
{
while(1){
pthread_t thread;
pthread_create(&thread, 0,th_fn,0);
pthread_detach(thread);
}
return 0;
}
题3
自己写同步逻辑,缺点是:它不是原子操作,会受到时间片的影响导致逻辑错误。
原子操作:在一个原子操作中,无论时间片是否使用完毕,原子操作总是在完整执行后才会释放时间片。
题4
轮流打印AB
- 使用互斥锁,实现两个线程轮流打印A-B-A-B
- 其中 ‘-’ 代表睡眠1秒,1s输出一个字符
代码:
/*
* 轮流打印AB.c
* 使用互斥锁,实现两个线程轮流打印A-B-A-B
* 其中 '-' 代表睡眠1秒,1s输出一个字符
*/
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct data{
char ch;
pthread_mutex_t mutex;
}xdata;
xdata dataX;
pthread_t tha,thb;
void* tha_fn(void* arg)
{
while(1){
pthread_mutex_lock(&dataX.mutex);
dataX.ch='A';
printf("%c\\n",dataX.ch);
sleep(1); //等待1s
pthread_mutex_unlock(&dataX.mutex);
sleep(1); //让B线程获取资源
}
}
void* thb_fn(void* arg)
{
while(1){
pthread_mutex_lock(&dataX.mutex);
dataX.ch='B';
printf("%c\\n",dataX.ch);
sleep(1); //等待1s
pthread_mutex_unlock(&dataX.mutex);
sleep(1); //让A线程获取资源
}
}
void sig_handler(int signum)
{
if(signum==SIGINT){
pthread_mutex_unlock(&dataX.mutex);
pthread_mutex_destroy(&dataX.mutex);
pthread_cancel(tha);
pthread_cancel(thb);
printf("\\npthread end!\\n");
exit(0);
}
}
int main(int argc, char **argv)
{
pthread_mutex_init(&dataX.mutex,0);
pthread_create(&tha,0,tha_fn,0);
pthread_create(&thb,0,thb_fn,0);
pthread_detach(tha);
pthread_detach(thb);
signal(SIGINT,sig_handler);
while(1);
return 0;
}
题5
使用互斥锁实现主线程从键盘录入字符串,子线程统计字符串中字符的个数
/*
* 3_str.c
*使用互斥锁实现主线程从键盘录入字符串,子线程统计字符串中字符的个数
*/
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
struct data{
char str[1024];
pthread_mutex_t mutex;
}xdata;
void sig_handler(int signum)
{
if(signum==SIGINT){
pthread_mutex_destroy(&xdata.mutex);
printf("\\nthread end\\n");
sleep(1);
exit(0);
}
}
void* th_fn1(void* arg)
{
while(1){
pthread_mutex_lock(&xdata.mutex);
printf("strlen : %d\\n",strlen(xdata.str));
pthread_mutex_unlock(&xdata.mutex);
usleep(100);
}
}
int main(int argc, char **argv)
{
pthread_t th1;
pthread_create(&th1,0,th_fn1,0);
pthread_mutex_init(&xdata.mutex,0);
while(1){
pthread_mutex_lock(&xdata.mutex);
printf("请输入字符串:");
scanf("%s",xdata.str);
pthread_mutex_unlock(&xdata.mutex);
usleep(100);
signal(SIGINT,sig_handler);
}
return 0;
}
题6:模拟服务器和客户端
要求:
- 编写3个.c文件1,2,3
- 其中 文件1模拟成服务器,文件2和3模拟成客户端
- 文件1要求有3个线程:主线程、处理文件2事物的线程、处理文件3线程
- 文件2发送一个信号给文件1,文件3发送另一个信号给文件1
- 1在接受信号后,分别打开文件io写入不同的数据
- 注意文件1 过程当中的同步问题
1号文件:
/*
* 1.c
* 编写3个.c文件1,2,3
* 其中 文件1模拟成服务器,文件2和3模拟成客户端
* 文件1要求有3个线程:主线程、处理文件2事物的线程、处理文件3线程
* 文件2发送一个信号给文件1,文件3发送另一个信号给文件1
* 1在接受信号后,分别打开文件io写入不同的数据
* 注意文件1 过程当中的同步问题
*
*/
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
pthread_t th2,th3;
char *fifo2="my_fifo2", *fifo3="my_fifo3";
void sig_handler(int signum){
if(signum==SIGUSR1){
printf("2号发送消息\\n");
}
if(signum==SIGUSR2){
printf("3号发送消息\\n");
}
if(signum==SIGINT){
remove(fifo2);
remove(fifo3);
printf("\\n程序结束\\n");
exit(0);
}
}
void* th2_fn(void* arg){
signal(SIGUSR1,sig_handler);
return NULL;
}
void* th3_fn(void* arg){
signal(SIGUSR2,sig_handler);
return NULL;
}
int main(int argc, char **argv)
{
int pid = getpid();
int fifofd2,fifofd3;
mkfifo(fifo2,0666);
fifofd2 = open(fifo2,O_WRONLY);
write(fifofd2,&pid,sizeof(int));
close(fifofd2);
mkfifo(fifo3,0666);
fifofd3 = open(fifo3,O_WRONLY);
write(fifofd3,&pid,sizeof(int));
close(fifofd3);
pthread_create(&th2,0,th2_fn,0);
pthread_create(&th3,0,th3_fn,0);
pthread_detach(th2);
pthread_detach(th3);
signal(SIGINT,sig_handler);
while(1);
return 0;
}
2号文件:
/*
* 2.c
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
int main_pid;
void sig_handler(int signum){
if(signum==SIGINT){
kill(main_pid,SIGUSR1);
}
}
int main(int argc, char **argv)
{
printf("按ctl+C向1发送信号\\n按ctrl+\\\\结束\\n");
int fifofd2;
mkfifo("my_fifo2",0666);
fifofd2 = open("my_fifo2",O_RDONLY);
read(fifofd2,&main_pid,sizeof(int));
close(fifofd2);
signal(SIGINT,sig_handler);
while(1);
return 0;
}
3号文件:
/*
* 3.c
*
*
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
int main_pid;
void sig_handler(int signum){
if(signum==SIGINT){
kill(main_pid,SIGUSR2);
}
}
int main(int argc, char **argv)
{
printf("按ctl+C向1发送信号\\n按ctrl+\\\\结束\\n");
int fifofd3;
mkfifo("my_fifo3",0666);
fifofd3 = open("my_fifo3",O_RDONLY);
read(fifofd3,以上是关于Linux练习_线程练习的主要内容,如果未能解决你的问题,请参考以下文章
Python练习册 第 0013 题: 用 Python 写一个爬图片的程序,爬 这个链接里的日本妹子图片 :-),(http://tieba.baidu.com/p/2166231880)(代码片段