我试图学习信号量以及它们如何在进程之间工作,所以我想创建一个程序,它从两个单独的for()循环中打印10倍字符串“abcd”。一个for()包含“ab”字符串,而另一个包含“cd”字符串。我认为代码很好,但显然不是。如果你能指出任何错误或者我有什么不明白的话,我将不胜感激。
以下是代码:
Item
其中一项产出:
int main(void)
{
int i;
char *p;
sem_t *sem; //First semaphore
sem_t *sem2; //Second semaphore
//create, initialize semaphores
sem = sem_open("/semaphore1", O_CREAT, 0644, 1);
sem2 = sem_open("/semaphore2", O_CREAT, 0644, 1);
if (fork()) //Child process
{
for (i=0;i<10;i++)
{
sem_wait(sem2); //Lock the semaphore
for (p="ab"; *p; p++)
{
write(1, p, 1);
usleep(100);
}
sem_post(sem); //Release the semaphore lock
}
wait(NULL);
}
else //Parent process
{
for (i=0;i<10;i++)
{
sem_wait(sem); //Lock the semaphore
for (p="cd\n"; *p; p++)
{
write(1, p, 1);
usleep(100);
}
sem_post(sem2); //Release the semaphore lock
}
}
//Close the Semaphores
sem_close(sem);
sem_unlink("/semaphore1");
sem_close(sem2);
sem_unlink("/semaphore2");
return 0;
}
答案 0 :(得分:1)
如评论中所述,您需要将第一个信号量(在以下代码中将sem1
重新命名为sem2
并将其重命名为0
)初始化为1
而不是fork()
父进程先行。
子进程和父进程注释放错位置(父进程从if
获得非零结果,因此在usleep()
中工作。即使没有调用sem_close()
,此版本也会产生所需的输出。名义上,只有一个进程需要使用sem_unlink()
和#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
int i;
char *p;
sem_t *sem1; // First semaphore
sem_t *sem2; // Second semaphore
// create, initialize semaphores
sem1 = sem_open("/semaphore1", O_CREAT, 0644, 0);
sem2 = sem_open("/semaphore2", O_CREAT, 0644, 1);
if (fork()) // Parent process
{
for (i = 0; i < 10; i++)
{
sem_wait(sem2); // Lock the semaphore
for (p = "ab"; *p; p++)
{
write(1, p, 1);
//usleep(100);
}
sem_post(sem1); // Release the semaphore lock
}
wait(NULL);
}
else // Child process
{
for (i = 0; i < 10; i++)
{
sem_wait(sem1); // Lock the semaphore
for (p = "cd\n"; *p; p++)
{
write(1, p, 1);
//usleep(100);
}
sem_post(sem2); // Release the semaphore lock
}
}
// Close the Semaphores
sem_close(sem1);
sem_unlink("/semaphore1");
sem_close(sem2);
sem_unlink("/semaphore2");
return 0;
}
,但由于您没有检查或报告任何错误,因此您不会注意到失败的调用。
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
示例输出:
private void Form_Load(object sender, EventArgs e)
{
var item = toolStripComboBox;
var createControl = item.Control.Parent.GetType().GetMethod("CreateControl",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
createControl.Invoke(item.Control.Parent, new object[] { true });