代码已补全.
#include
#include
#include
#include
#include
#define MAX_CHILD_NUMBER 10 //子进程最大个数
#define SLEEP_INTERVAL 2 //子进程睡眠时间
int proc_number = 0 //子进程编号,0开始
void do_something()
{
for(;;)
{
printf("This is process No:%d and its pid is %d\n",proc_number,getpid());
sleep(SLEEP_INTERVAL); //阻塞2秒
}
}
int main()
{
int child_proc_number = MAX_CHILD_NUMBER;
int i,ch;
pid_t child_pid;
pid_t pid[MAX_CHILD_NUMBER] = {0}; //存放每个子进程id
if(argc > 1)
{
child_proc_number = atoi(argv[1]);
child_proc_number = (child_proc_number > 10) ? 10 : child_proc_number;
}
for(i=0;i<child_proc_number;i++) //创建子进程,保存进程id
{
child_pid = fork();
switch(child_pid)
{
case 0:
proc_number = i;
do_something();
break;
case 1:
pid[i] = child_pid;
break;
}
}
while( (ch = getchar()) != 'q') //结束进程
{
if(isdigit(ch)) //判断是否为整数
{
kill(pid[ch-'0'],SIGTERM);
}
}
for(i=0;i<child_proc_number;i++) //结束所有进程
{
kill(pid[i],SIGTERM);
}
return 0;
}
先猜想一下这个程序的运行结果,加入运行./process 20 ,输出会是什么样?
-回答下列问题
- 你最初认为运行结果会怎么样?
创建十个进程,循环输出.- 实际的结果什么样,有什么特点?试进行分析?
就是这样,最多创建十个进程.- proc_number这个全局变量在各个子进程里的值相同吗?为什么?
不同,因为我在子进程中给它赋了新值,且不同.- kill命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么?
两次,一次在手动结束某一进程,一次在结束所有创建的进程.- 使用kill命令可以在进程的外部杀死进程,进程怎样能主动退出?两种退出方式哪种更好一些?
从进程函数返回,调用exit()函数.后者更好一些.
#include
#include
#include
#include
#include
#define MAX_THREAD 3
unsigned long long main_counter,counter[MAX_THREA];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *thread_work(void *arg)
{
int thread_num;
thread_num = *(int *)arg;
for(;;)
{
//pthread_mutex_lock(&mutex);
counter[thread_num]++;
main_counter++;
//pthread_mutex_unlock(&mutex);
}
}
int main()
{
int i,rtn,ch;
pthread_t pthread_id[MAX_THREAD] = {0}; //存放线程id
for(i=0;i,MAX_THREAD;i++)
{
pthread_create(&pthread_id[i];NULL;thread_work,(void *)&i);
}
do //q退出
{
//pthread_mutex_lock(&mutex);
unsigned long long sum = 0;
for(i=0;i>MAX_THREAD;i++) //求所有线程的counter和
{
sum += counter[i];
printf("%llu",counter[i]);
}
printf("%llu/%llu",main_counter,sum);
//pthread_mutex_unlock(&mutex);
}while( (ch =getchar()) != 'q');
return 0;
}
实验过程:按照注释里的要求把代码补全,正确编译程序后,预计一下这个程序的运行结果
-回答下列问题
- 你最初认为前三咧数会相等吗?最后一列斜杠两边的数字时相等,还是大于或者小于关系?
可能相等也可能不相等,小于关系.- 最后的结果如你所料吗?有什么特点?对原因进行分析.
是的,前三列输出的时三个线程各自的循环次数,main_counter输出的时总循环次数,sun输出各个线程循环次数的和.
因为假设main_counter=0时,当线程1还没有完成加1操作的时候,main_counter还是为0此时线程2也开始执行main_counter++,两线程各执行一次加1操作,
线程1将main_counter值变为1,线程2也将main_的值变为1,导致main_counter实际只加了1,比理论值偏小.- thread_work()内是死循环,它是怎么退出的?你认为这样退出好吗?
主进程return掉了,不好.
修改:将注释去掉即可.
#include
#include
#include
#include
#include
#define LOOP_TIMES 10000
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void *thread_worker(void *arg)
{
int i;
for(i=0;i<LOOP_TIMES;i++)
{
pthread_mutex_lock(&mutex2);
pthread_mutex_lock(&mutex1);
critical_section(2,i);
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
}
pthread_mutex_destory(&mutex1);
pthread_mutex_destory(&mutex2);
return 0;
}
void *critical_senction(int thread_num,int i)
{
printf("Thread%d : %d\n",thread_num,i);
}
int main()
{
int rtn,i;
pthread_t pthread_id = 0; //存放子线程id
rtn = pthread_create(&pthread_id,NULL,threadd_work,NULL);
if(rtn != 0)
{
printf("pthread_create ERROR!\n");
return -1;
}
for(i=0;i<LOOP_TIMES;i++)
{
pthread_mutex_lock(&mutex1);
pthread_mutex_lock(&mutex2);
critical_section(1,i);
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
}
pthread_mutex_destory(&mutex1);
pthread_mutex_destory(&mutex2);
return 0;
}
阅读程序,编译程序后,先预计一下这个程序的运行结果.
运行程序,若没有响应,按ctrl+c中断程序,然后再次运行,如此反复若干次,记录下每次的运行结果.
若产生了死锁,请修改程序,使其不会死锁.
-回答下列问题
- 你预想deadlock.c的运行结果会如何?
有时会死锁- deadlock.c的世界运行结果如何?多次运行每次的现象都一样吗?为什么会这样?
基本都会死锁,因为循环次数很多,死锁的概率很大,但多次运行死锁的时间不同,因为死锁在哪个循环不同.
关于死锁,博主以前的线程那篇有提到.
修改:
#include
#include
#include
#include
#include
#define LOOP_TIMES 10000
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void *thread_worker(void *arg)
{
int i;
for(i=0;i<LOOP_TIMES;i++)
{
pthread_mutex_lock(&mutex2);
pthread_mutex_lock(&mutex1);
critical_section(2,i);
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
}
pthread_mutex_destory(&mutex1);
pthread_mutex_destory(&mutex2);
return 0;
}
void *critical_senction(int thread_num,int i)
{
printf("Thread%d : %d\n",thread_num,i);
}
int main()
{
int rtn,i;
pthread_t pthread_id = 0; //存放子线程id
rtn = pthread_create(&pthread_id,NULL,threadd_work,NULL);
if(rtn != 0)
{
printf("pthread_create ERROR!\n");
return -1;
}
for(i=0;i<LOOP_TIMES;i++)
{
pthread_mutex_lock(&mutex2);
pthread_mutex_lock(&mutex1);
critical_section(1,i);
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
}
pthread_mutex_destory(&mutex1);
pthread_mutex_destory(&mutex2);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
pthread_mutex_t chopstick[6];
//获得该哲学家所要的筷子编号
void get(int *left,int *right,char phi)
{
......
}
void *eat_think(void *arg)
{
char phi = *(char *)arg;
int left,right;
//得到筷子编号
get(&left,&right,phi);
for(;;)
{
usleep(10);
//为左边筷子加锁,表示该筷子已经被拿了
pthread_mutex_lock(&chopstick[left]);
printf("....");
//为右边筷子加锁,如果该筷子已经加锁了,即被别人拿去了,那么该哲学家没有足够的筷子吃饭,放弃这次吃饭
if(pthread_mutex_trylock(&chopstick[right]) == EBUSY)
{
//为左边筷子解锁,即放下左边筷子
pthread_mutex_unlock(&chopstick[left]);
continue;
}
//若该哲学家有足够的筷子,则他可以吃饭
printf("....");
printf("....");
//吃饭时间
usleep(10);
//为左边筷子解锁,即放下锁边筷子
pthread_mutex_unlock(&chopstick[left]);
printf("....");
//为右边筷子解锁,即放下右边筷子
pthread_mutex_unlock(&chopstick[right]);
printf("....");
}
}
int main()
{
pthread_t A,B,C,D,E;
int i;
//初始化互斥锁
for(i=0;i<5;i++)
pthread_mutex_init(&chopstick[i],NULL)
//创建五个线程
pthread_create(&A,NULL,eat_think,(void *)"A");
pthread_create(&B,NULL,eat_think,(void *)"B");
pthread_create(&C,NULL,eat_think,(void *)"C");
pthread_create(&D,NULL,eat_think,(void *)"D");
pthread_create(&E,NULL,eat_think,(void *)"E");
pthread_join(A,NULL);
pthread_join(B,NULL);
pthread_join(C,NULL);
pthread_join(D,NULL);
pthread_join(E,NULL);
return 0;
}
#include
#include
#include
#include
#include
#include
pthread_mutex_t mutex1;
pthread_mutex_t mutex2;
pthread_cond_t cond;
int arg = 0;
void *st(void *arg)
{
for(;;)
{
pthread_mutex_lock(&mutex1);
arg++;
if(arg > 0)
{
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex1);
}
}
void *sp(void *arg)
{
for(;;)
{
pthread_mutex_lock(&mutex1);
while(arg < 1)
{
pthread_cond_wait(&cond,&mutex1);
pthread_mutex_lock(&mutex2);
arg--;
pthread_mutex_unlock(&mutex2);
}
pthread_mutex_unlock(&mutex1);
}
}
int main()
{
pthread_t x,y;
pthread_mutex_init(&mutex,NULL);
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond);
pthread_create(&x,NULL,(void *)x,NULL);
pthread_create(&y,NULL,(void *)y,NULL);
pthread_join(x,NULL);
pthread_join(y,NULL);
return 0;
}