题目
t1
利用fork pipe实现 cat /etc/passwd | wc -l 命令
//利用fork pipe实现 cat /etc/passwd | wc -l 命令
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/string.h>
#include <fcntl.h>
int fd[2];
void mysys(char *cmd1,char *cmd2)
{
char c1[100];
char c2[100];
strcpy(c1,cmd1);
strcpy(c2,cmd2);
pid_t pid;
pipe(fd);
/*创建子进程,管道的所有操作都在这里面完成*/
pid=fork();
if (pid == 0) {
// child
//cat输出到屏幕的内容重定向到fd[1]管道写端
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
// execl("/bin/sh","sh","-c",cmd1 ,NULL);
execlp("cat","cat","/etc/passwd",NULL);
//write(1, "hello", 6);
exit(0);
}
// parent
// int file=open("log.txt",O_CREAT|O_RDWR,666);
//标准输入定向到管道输入端
//wc直接到管道读端去读
dup2(fd[0], 0);
//标准输入定向到管道输入端
// dup2(file,1);
close(fd[0]);
close(fd[1]);
execlp("wc","wc","-l",NULL);
//read(0, buf, sizeof(buf));
//execl("/bin/sh","sh","-c",cmd2 ,NULL);
//printf("Receive:%s\n", buf);
//return 0;
}
int main()
{
printf("> ");
char command[100];
/*分割两条命令,分别存入cmd1,和cmd2中。
以 | 为分隔符,将命令以及参数字符串存入*/
fgets(command,100,stdin);
char *cmd1,*cmd2,*filename;
cmd1= strtok(command," ");
// puts(cmd1);
filename= strtok(NULL,"|");
//puts(filename);
cmd2= strtok(NULL,"\n");
//puts(cmd2);
//创建新数组地址
char *command1= (char *)malloc(strlen(cmd1)+strlen(filename)+1);
char *command2= (char *)malloc(strlen(cmd2)+strlen(filename)+1);
strcpy(command1,cmd1);
strcat(command1," ");
strcat(command1,filename);
//puts(command1);
strcpy(command2,cmd2);
// puts(command2);
mysys(command1,command2);
return 0;
}
2019 t2
10个子进程计算0100之,和第一个进程计算010,第二计算11~20,以此类推。 并利用管道把结果返回到主进程
//10个子进程计算0~100,第一个进程计算0~10,第二计算11~20,以此类推。 并利用管道把结果返回到主进程
//(open函数)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//(read/write)(pipe) (sleep)
#include <unistd.h>
//(进程)
#include <stdio.h>
//(exit)
#include <stdlib.h>
//pthread.h包含了函数pthread_create的声明
#include <pthread.h>
int main()
{
int pid;
int allsum=0;
int fds[20];
int i;
for(i=0;i<20;i++)
{
pipe(&fds[i*2]);
}
for( i=0;i<10;i++)
{
pid = fork();
if (pid == 0)
{
int j=0;
int sum=0;
for(j=(i*10+1);j<=(i+1)*10;j++)
sum+=j;
write(fds[i*2+1], &sum,sizeof(int));
for(i=0;i<20;i++)
close(fds[i]);
exit(0);
}
}
// parent
for (i = 0; i < 10; i++) {
int result=0;
read(fds[i*2],&result,sizeof(int));
allsum += result;
}
for( i =0; i<20;i++)
close(fds[i]);
printf("sum = %d\n", allsum);
return 0;
}
2019 t3
2个线程计算1100,第一个计算startmiddle,第二个计算middle~end。
#include <stdio.h>
#include <pthread.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdlib.h>
struct params
{
int start;
int end;
};
struct result
{
int sum;
};
void *compute(void *args)
{
struct params *param=(struct params*)args;
int sum=0;
int i;
for(i=param->start;i<=param->end;i++)
sum+=i;
struct result *result=malloc(sizeof(struct result));
result->sum=sum;
return result;
}
int parallel_add(int start, int end)
{
int middle=(start+end)/2;
struct params param[2];
pthread_t worker[2];
int sum=0;
int i=0;
struct result *result;
struct params *p_param=param;
p_param->start=start;
p_param->end=middle;
pthread_create(&worker[0],NULL,compute,p_param);
p_param++;
p_param->start=middle+1;
p_param->end=end;
pthread_create(&worker[1],NULL,compute,p_param);
for(i=0;i<2;i++)
{
pthread_join(worker[i],(void**)&result);
sum+=result->sum;
free(result);
}
return sum;
}
int main()
{
// 1+2+3 ... + 100 = 5050
printf("sum = %d\n", parallel_add(1, 101));
return 0;
}
2019 t4
4个子进程,分别为爹妈儿女。爹往盘子里放苹果,儿子消耗苹果。妈往盘子里放橘子,女儿消耗橘子。盘子里只容许放一个水果。
使程序按如下结果运行循环
put apple
get apple
put orange
get orange
#include <stdio.h>
#include <pthread.h>
int temp=0;
pthread_mutex_t mutex;
pthread_cond_t wait_apple;
pthread_cond_t wait_orange;
pthread_cond_t full_apple;
pthread_cond_t full_orange;
void *father_entry(void *arg)
{
while(1)
{ pthread_mutex_lock(&mutex);
while(temp!=0)
pthread_cond_wait(&wait_orange,&mutex);
temp=1;
puts("put apple");
pthread_cond_broadcast(&full_apple);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void *mother_entry(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
while(temp!=0)
pthread_cond_wait(&wait_apple,&mutex);
temp=2;
puts("put orange");
pthread_cond_broadcast(&full_orange);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void *son_entry(void *arg)
{
while(1)
{
pthread_mutex_lock(&mutex);
while(temp!=1)
pthread_cond_wait(&full_apple,&mutex);
temp=0;
puts("get apple");
pthread_cond_broadcast(&wait_apple);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void *daughter_entry(void *arg)
{
while(1){
pthread_mutex_lock(&mutex);
while(temp!=2)
pthread_cond_wait(&full_orange,&mutex);
temp=0;
puts("get orange");
pthread_cond_broadcast(&wait_orange);
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
int main()
{
pthread_t father_thread;
pthread_t mother_thread;
pthread_t son_thread;
pthread_t daughter_thread;
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&wait_apple,NULL);
pthread_cond_init(&wait_orange,NULL);
pthread_cond_init(&full_apple,NULL);
pthread_cond_init(&full_orange,NULL);
temp=0;
pthread_create(&father_thread, NULL, &father_entry, NULL);
sleep(1);
pthread_create(&mother_thread, NULL, &mother_entry, NULL);
pthread_create(&son_thread, NULL, &son_entry, NULL);
pthread_create(&daughter_thread, NULL, &daughter_entry, NULL);
while (1);
return 0;
}
2016 t1
主进程创建1个子进程
主进程通过管道与子进程连接
子进程的标准输出连接到管道的写端
主进程的标准输入连接到管道的读端
在子进程中调用exec(“echo”, “echo”, “hello world”, NULL)
在父进程中调用read(0, buf, sizeof(buf)),从标准输入中获取子进程发送的字符串,并打印出来
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fds[2];
int buf[512];
pipe(fds);
pid_t pid;
pid = fork();
int readsize;
if(pid == 0)
{
dup2(fds[1],STDOUT_FILENO);
execlp("echo", "echo", "hello world", NULL);
exit(0);
}
else if (pid > 0)
{
readsize = read(fds[0], buf, 512);
write(STDOUT_FILENO, buf, readsize);
}
close(fds[0]);
close(fds[1]);
return 0;
}
2016 t2
主进程创建2个子进程,主进程通过两个管道分别与两个子进程连接
第一个子进程计算从1加到50的和,并将结果通过管道送给父进程
第一个子进程计算从50加到100的和,并将结果通过管道送给父进程
父进程读取两个子进程的结果,将他们相加,打印出来,结果为5050
2016 t3
1.主线程创建10个子线程 - 第0个子线程计算从01加到10的和 - 第1个子线程计算从11加到20的和 - 第2个子线程计算从21加到30的和 - … - 第9个子线程计算从91加到100的和 2. 主线程归并10个子线程的计算结果,最终结果为5050 3. 本题必须使用线程参数来完成
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
typedef struct {
int from;
int to;
int ans;
} Arg;
void *calc(void *arg)
{
Arg *p = arg;
int i;
p->ans = 0;
for(i = p->from; i<= p->to; ++i)
p->ans += i;
return NULL;
}
int main(void)
{
pthread_t ths[10];
Arg args[10];
int i, sum=0;
for(i = 0; i< 10; ++i)
{
args[i].from = i*10 + 1;
args[i].to = (i+1) * 10;
pthread_create(ths + i, 0, calc, args + i);
}
for(i = 0; i< 10; ++i)
pthread_join(ths[i], NULL);
for(i = 0; i<10; ++i)
sum += args[i].ans;
printf("%d\n", sum);
return 0;
}
2016 t4
- 主线程创建4个子线程T1、T2、T3、T4,主线程在4个子线程退出后,才退出
- 线程T1、T2、T3、T4的运行时代码如下:
#include <unistd.h> // sleep函数声明在该头文件中
void *T1_entry(void *arg)
{
sleep(2); // 睡眠2秒,不准删除此条语句,否则答题无效
puts(“T1”);
}
void *T2_entry(void *arg)
{
sleep(1); // 睡眠1秒,不准删除此条语句,否则答题无效
puts(“T2”);
}
void *T3_entry(void *arg)
{
sleep(1); // 睡眠1秒,不准删除此条语句,否则答题无效
puts(“T3”);
}
void *T4_entry(void *arg)
{
puts(“T4”);
}
- 使用信号量或者条件变量机制(而不是使用sleep函数),使得这四个线程满足如下制约关系:
- T1的print语句执行后,T2和T3才可以执行print语句
- T2和T3的print语句执行后,T4才可以执行print语句
- 程序输出结果为
T1
T2
T3
T4
或者
T1
T3
T2
T4
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_cond_t s1_signal = PTHREAD_COND_INITIALIZER;
pthread_cond_t s2_signal = PTHREAD_COND_INITIALIZER;
int t1_gone = 0, t2_gone = 0, t3_gone = 0;
pthread_mutex_t s1_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t s2_mutex = PTHREAD_MUTEX_INITIALIZER;
void *T1_entry(void *arg)
{
pthread_mutex_lock(&s1_mutex);
sleep(2);
puts("T1");
t1_gone = 1;
pthread_cond_broadcast(&s1_signal);
pthread_mutex_unlock(&s1_mutex);
return NULL;
}
void *T2_entry(void *arg)
{
pthread_mutex_lock(&s1_mutex);
while(!t1_gone)
pthread_cond_wait(&s1_signal, &s1_mutex);
pthread_mutex_unlock(&s1_mutex);
sleep(1);
puts("T2");
pthread_mutex_lock(&s2_mutex);
t2_gone = 1;
pthread_cond_signal(&s2_signal);
pthread_mutex_unlock(&s2_mutex);
return NULL;
}
void *T3_entry(void *arg)
{
pthread_mutex_lock(&s1_mutex);
while(!t1_gone)
pthread_cond_wait(&s1_signal, &s1_mutex);
pthread_mutex_unlock(&s1_mutex);
sleep(1);
puts("T3");
pthread_mutex_lock(&s2_mutex);
t3_gone = 1;
pthread_cond_signal(&s2_signal);
pthread_mutex_unlock(&s2_mutex);
return NULL;
}
void *T4_entry(void *arg)
{
pthread_mutex_lock(&s2_mutex);
while(!t2_gone || !t3_gone)
pthread_cond_wait(&s2_signal, &s2_mutex);
puts("T4");
pthread_mutex_unlock(&s2_mutex);
return NULL;
}
int main(void)
{
pthread_t t1,t2,t3,t4;
pthread_create(&t1, 0, T1_entry, NULL);
pthread_create(&t2, 0, T2_entry, NULL);
pthread_create(&t3, 0, T3_entry, NULL);
pthread_create(&t4, 0, T4_entry, NULL);
pthread_join(t4, NULL);
return 0;
}
第二种
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
typedef struct {
int value;
pthread_mutex_t mutex;
pthread_cond_t cond;
}sema_t;
sema_t t1_2_ready;
sema_t t1_3_ready;
sema_t t2_ready;
sema_t t3_ready;
void sema_init(sema_t *sema, int value)
{
sema->value = value;
pthread_mutex_init(&sema->mutex, NULL);
pthread_cond_init(&sema->cond, NULL);
}
void sema_wait(sema_t *sema)
{
pthread_mutex_lock(&sema->mutex);
while (sema->value <= 0)
pthread_cond_wait(&sema->cond, &sema->mutex);
sema->value--;
pthread_mutex_unlock(&sema->mutex);
}
void sema_signal(sema_t *sema)
{
pthread_mutex_lock(&sema->mutex);
++sema->value;
pthread_cond_signal(&sema->cond);
pthread_mutex_unlock(&sema->mutex);
}
void *T1_entry(void *arg)
{
sleep(2); // 睡眠2秒,不准删除此条语句,否则答题无效
puts("T1");
sema_signal(&t1_2_ready);
sema_signal(&t1_3_ready);
}
void *T2_entry(void *arg)
{
sema_wait(&t1_2_ready);
sleep(1); // 睡眠1秒,不准删除此条语句,否则答题无效
puts("T2");
sema_signal(&t2_ready);
}
void *T3_entry(void *arg)
{
sema_wait(&t1_3_ready);
sleep(1); // 睡眠1秒,不准删除此条语句,否则答题无效
puts("T3");
sema_signal(&t3_ready);
}
void *T4_entry(void *arg)
{
sema_wait(&t2_ready);
sema_wait(&t3_ready);
puts("T4");
}
int main()
{
sema_init(&t1_2_ready,0);
sema_init(&t1_3_ready,0);
sema_init(&t2_ready,0);
sema_init(&t3_ready,0);
pthread_t T1,T2,T3,T4;
pthread_create(&T1, NULL, T1_entry, NULL);
pthread_create(&T2, NULL, T2_entry, NULL);
pthread_create(&T3, NULL, T3_entry, NULL);
pthread_create(&T4, NULL, T4_entry, NULL);
pthread_join(T1,NULL);
pthread_join(T2,NULL);
pthread_join(T3,NULL);
pthread_join(T4,NULL);
return 0;
}
ring.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define N 10
#define LOOPCOUNT 25
void *add(void *arg){
int *num = (int *)arg;
num[1] = num[0] + 1;
int *result = num;
}
int main()
{
int buff[N][2];
int i = 0;
for(i = 0;i < N;i++)
{
buff[i][0]=0;
buff[i][1]=0;
}
pthread_t tids[N];
i = 0;
int count = 0;
while(i < N)
{
count++;
if(count == LOOPCOUNT)
break;
printf("from T[%d]",i+1);
pthread_create(&tids[i],NULL,add,(void *)&buff[i]);
pthread_join(tids[i],NULL);
int result = buff[i][1];
i = (i+1) % N;
buff[i][0] = result;
printf("to T[%d] send %d\n",i+1,result);
}
return 0;
}